Exemplo n.º 1
0
/**
 * Memoizes callbacks and returns there value instead of calling them
 *
 * @param callable $callback Callable closure or function
 * @param array $arguments Arguments
 * @param array|string $key Optional memoize key to override the auto calculated hash
 * @return mixed
 */
function memoize($callback, array $arguments = array(), $key = null)
{
    Exceptions\InvalidArgumentException::assertCallback($callback, __FUNCTION__, 1);
    static $keyGenerator = null, $storage = array();
    if (!$keyGenerator) {
        $keyGenerator = function ($value) use(&$keyGenerator) {
            $type = gettype($value);
            if ($type === 'array') {
                $key = join(':', map($value, $keyGenerator));
            } elseif ($type === 'object') {
                $key = get_class($value) . ':' . spl_object_hash($value);
            } else {
                $key = (string) $value;
            }
            return $key;
        };
    }
    if ($key === null) {
        $key = $keyGenerator(array_merge(array($callback), $arguments));
    } else {
        $key = $keyGenerator($key);
    }
    if (!isset($storage[$key]) && !array_key_exists($key, $storage)) {
        $storage[$key] = call_user_func_array($callback, $arguments);
    }
    return $storage[$key];
}
Exemplo n.º 2
0
/**
 * Alias for Functional\first
 *
 * @param Traversable|array $collection
 * @param callable $callback
 * @return mixed
 */
function head($collection, $callback = null)
{
    Exceptions\InvalidArgumentException::assertCollection($collection, __FUNCTION__, 1);
    if ($callback !== null) {
        Exceptions\InvalidArgumentException::assertCallback($callback, __FUNCTION__, 2);
    }
    return first($collection, $callback);
}
Exemplo n.º 3
0
/**
 * Iterates over a collection of elements, yielding each in turn to a callback function. Each invocation of $callback
 * is called with three arguments: (element, index, collection)
 *
 * @param Traversable|array $collection
 * @param callable $callback
 * @return null
 */
function each($collection, $callback)
{
    Exceptions\InvalidArgumentException::assertCollection($collection, __FUNCTION__, 1);
    Exceptions\InvalidArgumentException::assertCallback($callback, __FUNCTION__, 2);
    foreach ($collection as $index => $element) {
        call_user_func($callback, $element, $index, $collection);
    }
}
Exemplo n.º 4
0
/**
 * @param Traversable|array $collection
 * @param callable $callback
 * @return array
 */
function reduce_left($collection, $callback, $initial = null)
{
    Exceptions\InvalidArgumentException::assertCollection($collection, __FUNCTION__, 1);
    Exceptions\InvalidArgumentException::assertCallback($callback, __FUNCTION__, 2);
    foreach ($collection as $index => $value) {
        $initial = call_user_func($callback, $value, $index, $collection, $initial);
    }
    return $initial;
}
Exemplo n.º 5
0
/**
 * Produces a new array of elements by mapping each element in collection through a transformation function (callback).
 * Callback arguments will be element, index, collection
 *
 * @param Traversable|array $collection
 * @param callable $callback
 * @return array
 */
function map($collection, $callback)
{
    Exceptions\InvalidArgumentException::assertCollection($collection, __FUNCTION__, 1);
    Exceptions\InvalidArgumentException::assertCallback($callback, __FUNCTION__, 2);
    $aggregation = array();
    foreach ($collection as $index => $element) {
        $aggregation[$index] = call_user_func($callback, $element, $index, $collection);
    }
    return $aggregation;
}
Exemplo n.º 6
0
/**
 * Returns true if all elements of the collection evaluate to true
 *
 * @param Traversable|array $collection
 * @return bool
 */
function truthy($collection)
{
    Exceptions\InvalidArgumentException::assertCollection($collection, __FUNCTION__, 1);
    foreach ($collection as $value) {
        if (!$value) {
            return false;
        }
    }
    return true;
}
Exemplo n.º 7
0
/**
 * Returns the first index holding specified value in the ccollection. Returns false if value was not found
 *
 * @param Traversable|array $collection
 * @param mixed $value
 * @return mixed
 */
function first_index_of($collection, $value)
{
    Exceptions\InvalidArgumentException::assertCollection($collection, __FUNCTION__, 1);
    foreach ($collection as $index => $element) {
        if ($element === $value) {
            return $index;
        }
    }
    return false;
}
Exemplo n.º 8
0
/**
 * Returns true if the collection contains the given value. If the third parameter is
 * true values will be compared in strict mode
 *
 * @param Traversable|array $collection
 * @param mixed $value
 * @param bool $strict
 * @return bool
 */
function contains($collection, $value, $strict = true)
{
    Exceptions\InvalidArgumentException::assertCollection($collection, __FUNCTION__, 1);
    foreach ($collection as $element) {
        if ($value === $element || !$strict && $value == $element) {
            return true;
        }
    }
    return false;
}
Exemplo n.º 9
0
/**
 * Returns the last index holding specified value in the ccollection. Returns false if value was not found
 *
 * @param Traversable|array $collection
 * @param mixed $value
 * @return mixed
 */
function last_index_of($collection, $value)
{
    Exceptions\InvalidArgumentException::assertCollection($collection, __FUNCTION__, 1);
    $matchingIndex = false;
    foreach ($collection as $index => $element) {
        if ($element === $value) {
            $matchingIndex = $index;
        }
    }
    return $matchingIndex;
}
Exemplo n.º 10
0
/**
 * Returns true if all of the elements in the collection pass the callback falsy test. Opposite of Functional\all().
 * Callback arguments will be element, index, collection.
 *
 * @param Traversable|array $collection
 * @param callable $callback
 * @return bool
 */
function none($collection, $callback)
{
    Exceptions\InvalidArgumentException::assertCollection($collection, __FUNCTION__, 1);
    Exceptions\InvalidArgumentException::assertCallback($callback, __FUNCTION__, 2);
    foreach ($collection as $index => $element) {
        if (call_user_func($callback, $element, $index, $collection)) {
            return false;
        }
    }
    return true;
}
Exemplo n.º 11
0
/**
 * Partitions a collection by callback result. The thruthy partition is the first one
 * (array index "0"), the falsy the second one (array index "1")
 *
 * @param Traversable|array $collection
 * @param callable $callback
 * @return array
 */
function partition($collection, $callback)
{
    Exceptions\InvalidArgumentException::assertCollection($collection, __FUNCTION__, 1);
    Exceptions\InvalidArgumentException::assertCallback($callback, __FUNCTION__, 2);
    $partitions = array(0 => array(), 1 => array());
    foreach ($collection as $index => $element) {
        $partitionKey = call_user_func($callback, $element, $index, $collection) ? 0 : 1;
        $partitions[$partitionKey][$index] = $element;
    }
    return $partitions;
}
Exemplo n.º 12
0
/**
 * Takes a collection and returns the difference of all elements
 *
 * @param Traversable|array $collection
 * @return integer|float
 */
function difference($collection, $initial = 0)
{
    Exceptions\InvalidArgumentException::assertCollection($collection, __FUNCTION__, 1);
    $result = $initial;
    foreach ($collection as $value) {
        if (is_numeric($value)) {
            $result -= $value;
        }
    }
    return $result;
}
Exemplo n.º 13
0
/**
 * @param Traversable|array $collection
 * @param callable $callback
 * @return array
 */
function reduce_right($collection, $callback, $initial = null)
{
    Exceptions\InvalidArgumentException::assertCollection($collection, __FUNCTION__, 1);
    Exceptions\InvalidArgumentException::assertCallback($callback, __FUNCTION__, 2);
    $data = array();
    foreach ($collection as $index => $value) {
        $data[] = array($index, $value);
    }
    while (list($index, $value) = array_pop($data)) {
        $initial = call_user_func($callback, $value, $index, $collection, $initial);
    }
    return $initial;
}
Exemplo n.º 14
0
/**
 * Calls the method named by $methodName on first value in the collection. Any extra arguments passed to invoke will be
 * forwarded on to the method invocation.
 *
 * @param Traversable|array $collection
 * @param string $methodName
 * @param array $arguments
 * @return array
 */
function invoke_first($collection, $methodName, array $arguments = array())
{
    Exceptions\InvalidArgumentException::assertCollection($collection, __FUNCTION__, 1);
    Exceptions\InvalidArgumentException::assertMethodName($methodName, __FUNCTION__, 2);
    foreach ($collection as $index => $element) {
        $value = null;
        $callback = array($element, $methodName);
        if (is_callable($callback)) {
            return call_user_func_array($callback, $arguments);
        }
    }
    return null;
}
Exemplo n.º 15
0
/**
 * Returns the minimum value of a collection
 *
 * @param Traversable|array $collection
 * @param callable $callback
 * @return array
 */
function minimum($collection)
{
    Exceptions\InvalidArgumentException::assertCollection($collection, __FUNCTION__, 1);
    $max = null;
    foreach ($collection as $index => $element) {
        if (!is_numeric($element)) {
            continue;
        }
        if ($element < $max || $max === null) {
            $max = $element;
        }
    }
    return $max;
}
Exemplo n.º 16
0
/**
 * Drop all elements from a collection after callback returns true
 *
 * @param Traversable|array $collection
 * @param callable|integer $callback
 * @return array
 */
function drop_last($collection, $callback)
{
    Exceptions\InvalidArgumentException::assertCollection($collection, __FUNCTION__, 1);
    Exceptions\InvalidArgumentException::assertCallback($callback, __FUNCTION__, 2);
    $result = array();
    $drop = false;
    foreach ($collection as $index => $element) {
        if (!$drop && !call_user_func($callback, $element, $index, $collection)) {
            break;
        }
        $result[$index] = $element;
    }
    return $result;
}
Exemplo n.º 17
0
/**
 * Looks through each element in the collection, returning the last one that passes a truthy test (callback).
 * Callback arguments will be element, index, collection
 *
 * @param Traversable|array $collection
 * @param callable $callback
 * @return mixed
 */
function last($collection, $callback = null)
{
    Exceptions\InvalidArgumentException::assertCollection($collection, __FUNCTION__, 1);
    if ($callback !== null) {
        Exceptions\InvalidArgumentException::assertCallback($callback, __FUNCTION__, 2);
    }
    $match = null;
    foreach ($collection as $index => $element) {
        if ($callback === null || call_user_func($callback, $element, $index, $collection)) {
            $match = $element;
        }
    }
    return $match;
}
Exemplo n.º 18
0
/**
 * Looks through each element in the collection, returning the first one that passes a truthy test (callback). The
 * function returns as soon as it finds an acceptable element, and doesn't traverse the entire collection. Callback
 * arguments will be element, index, collection
 *
 * @param Traversable|array $collection
 * @param callable $callback
 * @return mixed
 */
function first($collection, $callback = null)
{
    Exceptions\InvalidArgumentException::assertCollection($collection, __FUNCTION__, 1);
    if ($callback !== null) {
        Exceptions\InvalidArgumentException::assertCallback($callback, __FUNCTION__, 2);
    }
    foreach ($collection as $index => $element) {
        if ($callback === null) {
            return $element;
        }
        if (call_user_func($callback, $element, $index, $collection)) {
            return $element;
        }
    }
}
Exemplo n.º 19
0
/**
 * Groups a collection by index returned by callback.
 *
 * @param Traversable|array $collection
 * @param callable $callback
 * @return array
 */
function group($collection, $callback)
{
    Exceptions\InvalidArgumentException::assertCollection($collection, __FUNCTION__, 1);
    Exceptions\InvalidArgumentException::assertCallback($callback, __FUNCTION__, 2);
    $groups = array();
    foreach ($collection as $index => $element) {
        $groupKey = call_user_func($callback, $element, $index, $collection);
        Exceptions\InvalidArgumentException::assertValidArrayKey($groupKey, __FUNCTION__);
        if (!isset($groups[$groupKey])) {
            $groups[$groupKey] = array();
        }
        $groups[$groupKey][$index] = $element;
    }
    return $groups;
}
Exemplo n.º 20
0
/**
 * Returns the average of all numeric values in the array or null if no numeric value was found
 *
 * @param Traversable|array $collection
 * @return null|float|int
 */
function average($collection)
{
    Exceptions\InvalidArgumentException::assertCollection($collection, __FUNCTION__, 1);
    $sum = null;
    $divisor = 0;
    foreach ($collection as $element) {
        if (is_numeric($element)) {
            $sum += $element;
            ++$divisor;
        }
    }
    if ($sum === null) {
        return null;
    }
    return $sum / $divisor;
}
Exemplo n.º 21
0
/**
 * Drop all elements from a collection until callback returns false
 *
 * @param Traversable|array $collection
 * @param callable $callback
 * @return array
 */
function drop_first($collection, $callback)
{
    Exceptions\InvalidArgumentException::assertCollection($collection, __FUNCTION__, 1);
    Exceptions\InvalidArgumentException::assertCallback($callback, __FUNCTION__, 2);
    $result = array();
    $drop = true;
    foreach ($collection as $index => $element) {
        if ($drop) {
            if (!call_user_func($callback, $element, $index, $collection)) {
                $drop = false;
            } else {
                continue;
            }
        }
        $result[$index] = $element;
    }
    return $result;
}
Exemplo n.º 22
0
/**
 * Returns all items from $collection except first element (head). Preserves $collection keys.
 * Takes an optional callback for filtering the collection.
 *
 * @param Traversable|array $
 * @param callable $callback
 * @return array
 */
function tail($collection, $callback = null)
{
    Exceptions\InvalidArgumentException::assertCollection($collection, __FUNCTION__, 1);
    if ($callback !== null) {
        Exceptions\InvalidArgumentException::assertCallback($callback, __FUNCTION__, 2);
    }
    $tail = array();
    $isHead = true;
    foreach ($collection as $index => $element) {
        if ($isHead) {
            $isHead = false;
            continue;
        }
        if (!$callback || call_user_func($callback, $element, $index, $collection)) {
            $tail[$index] = $element;
        }
    }
    return $tail;
}
Exemplo n.º 23
0
/**
* Returns a array of unique elements
*
* @param Traversable|array $collection
* @param callable $callback
* @return array
*/
function unique($collection, $callback = null, $strict = true)
{
    Exceptions\InvalidArgumentException::assertCollection($collection, __FUNCTION__, 1);
    if ($callback != null) {
        Exceptions\InvalidArgumentException::assertCallback($callback, __FUNCTION__, 2);
    }
    $indexes = array();
    $aggregation = array();
    foreach ($collection as $key => $element) {
        if ($callback) {
            $index = call_user_func($callback, $element, $key, $collection);
        } else {
            $index = $element;
        }
        if (!in_array($index, $indexes, $strict)) {
            $aggregation[$key] = $element;
            $indexes[] = $index;
        }
    }
    return $aggregation;
}
Exemplo n.º 24
0
/**
 * Recombines arrays by index and applies a callback optionally
 *
 * @param Traversable|array $collection One or more callbacks
 * @param callable $callback Optionally the last argument can be a callback
 * @return array
 */
function zip($collection)
{
    $args = func_get_args();
    $callback = null;
    if (is_callable(end($args))) {
        $callback = array_pop($args);
    }
    foreach ($args as $position => $collection) {
        Exceptions\InvalidArgumentException::assertCollection($collection, __FUNCTION__, $position + 1);
    }
    $result = array();
    foreach (func_get_arg(0) as $index => $value) {
        $zipped = array();
        foreach ($args as $arg) {
            $zipped[] = isset($arg[$index]) ? $arg[$index] : null;
        }
        if ($callback !== null) {
            $zipped = call_user_func_array($callback, $zipped);
        }
        $result[] = $zipped;
    }
    return $result;
}
Exemplo n.º 25
0
/**
 * Alias of Functional\select()
 *
 * @param Traversable|array $collection
 * @param callable $callback
 * @return array
 */
function filter($collection, $callback)
{
    Exceptions\InvalidArgumentException::assertCollection($collection, __FUNCTION__, 1);
    Exceptions\InvalidArgumentException::assertCallback($callback, __FUNCTION__, 2);
    return select($collection, $callback);
}