Location: PHPKode > scripts > FuncUtility > funcutility/FuncUtility.php
<?php
/**
 * Allows to use FP-like features for arrays, strings, SPL iterators and even results
 * returned from callbacks
 *
 * This class adds a lot of syntax sugar to your recordset processing routines or other
 * similar tasks when you don't want to write a loop construct. You will never see the
 * calls of FuncUtility methods in the Frontier's core. It uses call_user_func(),
 * which is slow. But I hope, it's performance will be improved someday though.
 *
 * @author Stanis Shramko <hide@address.com>
 */
class FuncUtility
{

  /**
   * Filters all elements of $set using the $callback
   *
   * @return array
   * @throws InvalidArgumentException
   */
  public static function filter($callback, $set)
  {
    if (!is_callable($callback))
    {
      throw new InvalidArgumentException(
        'The first argument is not callable');
    }
    $values = array();
    if (is_callable($set))
    {
      while ($value = call_user_func($set))
      {
        if (call_user_func($callback, $value))
        {
          $values[] = $value;
        }
      }
    }
    else
    {
      foreach (($set = self::prepareIterable($set)) as $value)
      {
        if (call_user_func($callback, $value))
          $values[] = $value;
      }
    }
    return $values;
  }

  /**
   * Applies the $callback to all elements of $set
   *
   * @return void
   * @throws InvalidArgumentException
   */
  public static function each($callback, $set)
  {
    if (!is_callable($callback))
    {
      throw new InvalidArgumentException(
        'The first argument is not callable');
    }
    if (is_callable($set))
    {
      while ($value = call_user_func($set))
      {
        call_user_func($callback, $value);
      }
    }
    else
    {
      foreach (($set = self::prepareIterable($set)) as $value)
      {
        call_user_func($callback, $value);
      }
    }
  }

  /**
   * Applies the $callback to all elements of $set
   *
   * @return array
   * @throws InvalidArgumentException
   */
  public static function map($callback, $set)
  {
    if (!is_callable($callback))
    {
      throw new InvalidArgumentException(
        'The first argument is not callable');
    }
    $values = array();
    if (is_callable($set))
    {
      while ($value = call_user_func($set))
      {
        $values[] = call_user_func($callback, $value);
      }
    }
    else
    {
      foreach (($set = self::prepareIterable($set)) as $value)
      {
        $values[] = call_user_func($callback, $value);
      }
    }
    return $values;
  }

  /**
   * Reduces the $set using $result
   *
   * @return array
   * @throws InvalidArgumentException
   */
  public static function reduce($callback, $set)
  {
    if (!is_callable($callback))
    {
      throw new InvalidArgumentException(
        'The first argument is not callable');
    }
    if (is_callable($set))
    {
      $result = call_user_func($set);
      while ($value = call_user_func($set))
      {
        $result = call_user_func($callback, $result, $value);
      }
    }
    else
    {
      $first = true;
      foreach (($set = self::prepareIterable($set)) as $value)
      {
        if (!$first)
        {
          $result = call_user_func($callback, $result,
            $value);
        }
        else
        {
          $result = $value;
          $first = false;
        }
      }
    }
    return $result;
  }

  /**
   * Prepares "something iterable"
   *
   * @param mixed $set
   * @return mixed array or Iterator
   */
  protected static function prepareIterable($set)
  {
    if (is_array($set) || $set instanceof Iterator)
    {
      return $set;
    }
    if (is_string($set))
    {
      return str_split($set);
    }
    throw new InvalidArgumentException('The second argument is not iterable');
  }

}
Return current item: FuncUtility