Skip to content

Sequence Functional Library

Jason Dent edited this page Jan 11, 2016 · 9 revisions

Sequence Functional Library for PHP

About Sequence

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.

Development Criteria

  • 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

Namespaces

  • Classes -- \Revinate\Sequence
  • Helper functions -- \Revinate\Sequence\fn

Use

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;

Sequence Class

At its root, Sequence is just an IteratorIterator with some functional methods. It is these methods that make Sequence useful.

Creating a Sequence

Using Sequence::make()

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();

Using new Sequence()

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();

The Methods:

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.

Map

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.

Filter

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

Reduce

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)

Traversing a sequence:

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.

Reference

Clone this wiki locally