-
Notifications
You must be signed in to change notification settings - Fork 4
Sequence Functional Library
A Sequence is an ordered collection of things (key-value pairs). Sequences can be created from arrays, objects, or iterators. Depending upon the source, the keys can be implied (the index into an array) or explicit (the field name for an object or assoc array). Behind the scenes, a Sequence is just an iterator and uses the build in SPL iterator classes.
Sequence was developed to provide a functional approach to working with arrays and iterators in PHP.
- Must support autocompletion in common IDEs.
- Must be PHP 5.3 compatible -- this is the reason generators are not used.
- Should be built up from first principles
- Should be kept clean and simple
- Each Method or Function should have a single purpose
- Classes --
\Revinate\Sequence
- Helper functions --
\Revinate\Sequence\fn
To make things easier, the following use statements are suggested. All examples will assume that these are in place.
use \Revinate\Sequence\Sequence;
use \Revinate\Sequence\fn;
At its root, Sequence is just an IteratorIterator with some functional methods. It is these methods that make Sequence useful.
The most common way to create a Sequence is to use Sequence::make()
.
Use the Sequence::make()
factory function to easily create a Sequence from an array, ArrayObject, Iterator, or anything that is Traversable.
Example:
$resultsById = Sequence::make($queryResults)->keyBy('id')->to_a();
It is a little bit more complicated to create a Sequence using new
because you must first have an Iterator.
$array = array(array('id'=>31415926,...),...);
$iter = new \ArrayIterator($array);
$seq = new Sequence($iter);
$resultsById = $seq->keyBy('id')->to_a();
There is a basic set of things you can do to a sequence: map, filter, and reduce. The other methods are really just specialized versions of these operations. These methods take functions as parameters that will be applied to the data in the Sequence. In general functions have the following signature: function ($value, $key)
and return a value.
This allows you to change the value or key into something different. For example, you would use map to convert id's into objects.
-
map - sets a new value based upon the value returned by the given function. Signature:
function ($value, $key)
-
mapKeys - sets a new key based upon result returned by the given function. Signature:
function ($key, $value)
-
keyBy - is an alias for mapKeys but with the signature flipped. Signature:
function ($value, $key)
-
pluck() - this is just an alias for
->map(fn\fnPluck())
- keys() - extracts the keys from the Sequence
- values() -- extracts the values from the Sequence, the keys become numeric starting at 0.
- sort() -- sorts values in the Sequence.
- asort() -- uses asort to sort the values in the Sequence.
- sortKeys() -- sorts the Sequence by the keys.
- groupBy() -- groups the Sequence values.
- flatten() -- flattens the Sequence values
- flattenOnce() -- flattens the Sequence values one level.
This allows you to filter out keys or values based upon some condition.
-
filter - filters out all values where the given function returns a falsy value. Signature:
function ($value, $key)
-
filterKeys - is just a special version of filter that changes the parameter order from ($value, $key) to ($key, $value). Signature:
function ($key, $value)
- limit($max) - limits the number of elements in the sequence to $max
- offset($count) - skips $count elements
This allows you to convert the entire sequence into something. This one take some getting used to, but is super powerful. The function Signature for all reduce functions is function ($target, $value, $key)
-
reduce($init, $function) - traverses all values in the Sequence applies $function. Signature:
function($target, $value, $key)
- to_a() - converts the entire sequence into an array. This is a form of reduce, but it is implemented using iterator_to_array for speed.
-
walk() - traverses all values in the Sequence and calls the given function. Signature:
function($value, $key)
-
first() - returns the first value where the give function returns true. Signature:
function($value, $key)
-
firstKey() -- returns the first value where the given function returns true. Signature:
function($key, $value)
Sequences should only be traversed once. In some cases, it is possible to rewind them and traverse them again, but that practice is discouraged.. Things that will traverse a sequence:
- foreach ($sequence as $key => $value)
- to_a() - converts the entire result into an array or assoc array depending upon the keys.
- reduce() - convert all the items in the sequence into a single object.
- walk() - for each item in the sequence, apply a function. The return value is ignored.
- flattenOnceNow() - like flattenOnce, but it does it immediately.