SkillAgentSearch skills...

Transducers.php

Composable algorithmic transformations in PHP (mostly a toy and unsupported)

Install / Use

/learn @mtdowling/Transducers.php
About this skill

Quality Score

0/100

Supported Platforms

Universal

README

=============== transducers-php

.. image:: https://badges.gitter.im/Join Chat.svg :target: https://gitter.im/mtdowling/transducers.php?utm_source=badge&utm_medium=badge&utm_campaign=pr-badge&utm_content=badge

Transducers <http://clojure.org/transducers>_ are composable algorithmic transformations. They are independent from the context of their input and output sources and specify only the essence of the transformation in terms of an individual element. Because transducers are decoupled from input or output sources, they can be used in many different processes - collections, streams, channels, observables, etc. Transducers compose directly, without awareness of input or creation of intermediate aggregates.

For more information about Clojure transducers and transducer semantics see the introductory blog post <http://blog.cognitect.com/blog/2014/8/6/transducers-are-coming>_ and this video <https://www.youtube.com/watch?v=6mTbuzafcII>_.

You can transduce anything that you can iterate over in a foreach-loop (e.g., arrays, \Iterator, Traversable, Generator, etc.). Transducers can be applied eagerly using transduce(), into(), to_array(), to_assoc(), to_string(); and lazily using to_iter(), xform(), or by applying a transducer stream filter.

::

composer.phar require mtdowling/transducers

Defining Transformations With Transducers

Transducers compose with ordinary function composition. A transducer performs its operation before deciding whether and how many times to call the transducer it wraps. You can easily compose transducers to create transducer pipelines. The recommended way to compose transducers is with the transducers\comp() function:

.. code-block:: php

use Transducers as t;

$xf = t\comp(
    t\drop(2),
    t\map(function ($x) { return $x + 1; }),
    t\filter(function ($x) { return $x % 2; }),
    t\take(3)
);

The above composed transducer is a function that creates a pipeline for transforming data: it skips the first two elements of a collection, adds 1 to each value, filters out even numbers, then takes 3 elements from the collection. This new transformation function can be used with various transducer application functions, including xform().

.. code-block:: php

$data = [1, 2, 3, 4, 5, 6, 7, 8, 9, 10];
$result = t\xform($data, $xf);

// Contains: [5, 7, 9]

Transducers

Transducers are functions that return a function that accept a reducing function array $xf and return a new reducing function array that wraps the provided $xf.

Here's how to create a transducer that adds $n to each value:

.. code-block:: php

$inc = function ($n = 1) {
    // Return a function that accepts a reducing function array $xf.
    return function (array $xf) use ($n) {
        // Return a new reducing function array that wraps $xf.
        return [
            'init'   => $xf['init'],
            'result' => $xf['result'],
            'step'   => function ($result, $input) use ($xf, $n) {
                return $xf['step']($result, $input + $n);
            }
        ];
    }
};

$result = t\xform([1, 2, 3], $inc(1));
// Contains: 2, 3, 4

.. _reducing-link:

Reducing Function Array

Reducing function arrays are PHP associative arrays that contain a 'init', 'step', and 'result' key that maps to a function.

+--------+-------------------------+------------------------------------------+ | key | arguments | Description | +========+=========================+==========================================+ | init | none | Invoked to initialize a transducer. This | | | | function should call the 'init' function | | | | on the nested reducing function array | | | | $xf, which will eventually call out | | | | to the transducing process. This function| | | | is only called when an initial value is | | | | not provided while transducing. | +--------+-------------------------+------------------------------------------+ | step | $result, $input | This is a standard reduction function | | | | but it is expected to call the | | | | $xf['step'] function 0 or more | | | | times as appropriate in the transducer. | | | | For example, filter will choose | | | | (based on the predicate) whether to call | | | | $xf or not. map will always call | | | | it exactly once. cat may call it | | | | many times depending on the inputs. | +--------+-------------------------+------------------------------------------+ | result | $result | Some processes will not end, but for | | | | those that do (like transduce), the | | | | 'result' function is used to produce | | | | a final value and/or flush state. This | | | | function must call the $xf['result'] | | | | function exactly once. | +--------+-------------------------+------------------------------------------+

Using Transducers

Transducers can be used in any number of ways. This library provides several methods that can be used to apply transducers.

transduce()


``function transduce(callable $xf, array $step, $coll, $init = null)``

Transform and reduce $coll by applying $xf($step)['step'] to each value.

- ``callable $xf``: Transducer function to apply.
- ``array $step``: Transformer array that has 'init', 'result', and 'step' keys
  that map to a callable.
- ``$coll``: Data to transform. Can be an array, iterator, or PHP stream
  resource.
- ``$init``: Optional first initialization value of the reduction. If this
  value is not provided, the ``$step['init']()`` function will be called to
  provide a default value.

.. code-block:: php

    use Transducers as t;

    $data = [[1, 2], [3, 4]];
    $xf = t\comp(
        t\flatten(),
        t\filter(function ($value) { return $value % 2; }),
    );
    $result = t\transduce($xf, t\array_reducer(), $data);

    // Contains: [1, 3]

When using this function, you can use any of the built-in reducing function
arrays as the ``$step`` argument:

- ``transducers\array_reducer()``: Creates a reducing function array that
  appends values to an array.

  .. code-block:: php

      $data = [[1, 2], [3, 4]];
      $result = t\transduce(t\flatten(), t\array_reducer(), $data);

      // Results contains [1, 2, 3, 4]

- ``transducers\stream_reducer()``: Creates a reducing function array that
  writes values to a stream resource. If no ``$init`` value is provided when
  transducing then a PHP temp stream will be used.

  .. code-block:: php

      $data = [[1, 2], [3, 4]];
      $result = t\transduce(t\flatten(), t\stream_reducer(), $data);
      fseek($result, 0);
      echo stream_get_contents($result);
      // Outputs: 1234

- ``transducers\string_reducer()``: Creates a reducing function array that
  concatenates each value to a string.

  .. code-block:: php

      $xf = t\flatten();
      // use an optional joiner on the string reducer.
      $reducer = t\string_reducer('|');
      $data = [[1, 2], [3, 4]];
      $result = t\transduce($xf, $reducer, $data);

      // Result is '1|2|3|4'

- ``transducers\assoc_reducer()``: Creates a reducing function array that adds
  key value pairs to an associative array. Each value must be an array that
  contains the array key in the first element and the array value in the second
  element.

- ``transducers\create_reducer()``: Convenience function that can be used to
  quickly create reducing function arrays. The first and only required argument
  is a step function that takes the accumulated result and the new value and
  returns a single result. The next, optional, argument is the init function
  that takes no arguments an returns an initialized result. The next, optional,
  argument is the result function which takes a single result argument and is
  expected to return a final result.

  .. code-block:: php

      $result = t\transduce(
          t\flatten(),
          t\create_reducer(function ($r, $x) { return $r + $x; }),
          [[1, 2], [3, 4]]
      );

      // Result is equal to 10

- ``transducers\operator_reducer()``: Creates a reducing function array that
  uses the provided infix operator to reduce the collection (i.e.,
  $result <operator> $input). Supports: '.', '+', '-', '*', and '/' operators.

  .. code-block:: php

      $result = t\transduce(
          t\flatten()
          t\operator_reducer('+'),
          [[1, 2], [[3], 4]]
      );

      // Result is equal to 10


xform()
~~~~~~~

``function xform($coll, callable $xf)``

Returns the same data type passed in as ``$coll`` with ``$xf`` applied.

``xform()`` using the following logic when returning values:

- ``array``: Returns an array using the provided array.
- ``associative array``: Turn the provided array into an indexed array, meaning
  that each value passed to the ``step`` reduce function is an array where
  the first element is the key and the second element is the value. When
  completed, ``xform()`` returns an associative array.
- ``\Iterator``: Returns an iterator in which ``$xf`` is applied lazily.
- ``resource``: Reads single bytes from the p
View on GitHub
GitHub Stars239
CategoryCustomer
Updated1mo ago
Forks13

Languages

PHP

Security Score

95/100

Audited on Mar 5, 2026

No findings