Skip to content

Commit

Permalink
feature twigphp#3803 pass the current key to reduce filter's callback…
Browse files Browse the repository at this point in the history
… (ju1ius)

This PR was squashed before being merged into the 3.x branch.

Discussion
----------

pass the current key to reduce filter's callback

See twigphp#3802 for context.

Commits
-------

4f2f3f8 pass the current key to reduce filter's callback
  • Loading branch information
fabpot committed Jan 25, 2023
2 parents 0d29e91 + 4f2f3f8 commit 609794c
Show file tree
Hide file tree
Showing 4 changed files with 27 additions and 11 deletions.
1 change: 1 addition & 0 deletions CHANGELOG
Original file line number Diff line number Diff line change
Expand Up @@ -11,6 +11,7 @@
* Fix optimizing closures callbacks
* Add a better exception when getting an undefined constant via `constant`
* Fix `if` nodes when outside of a block and with an empty body
* Arrow functions passed to the "reduce" filter now accept the current key as a third argument

# 3.4.3 (2022-09-28)

Expand Down
10 changes: 5 additions & 5 deletions doc/filters/reduce.rst
Original file line number Diff line number Diff line change
Expand Up @@ -4,21 +4,21 @@
The ``reduce`` filter iteratively reduces a sequence or a mapping to a single
value using an arrow function, so as to reduce it to a single value. The arrow
function receives the return value of the previous iteration and the current
value of the sequence or mapping:
value and key of the sequence or mapping:

.. code-block:: twig
{% set numbers = [1, 2, 3] %}
{{ numbers|reduce((carry, v) => carry + v) }}
{# output 6 #}
{{ numbers|reduce((carry, v, k) => carry + v * k) }}
{# output 8 #}
The ``reduce`` filter takes an ``initial`` value as a second argument:

.. code-block:: twig
{{ numbers|reduce((carry, v) => carry + v, 10) }}
{# output 16 #}
{{ numbers|reduce((carry, v, k) => carry + v * k, 10) }}
{# output 18 #}
Note that the arrow function has access to the current context.

Expand Down
13 changes: 7 additions & 6 deletions src/Extension/CoreExtension.php
Original file line number Diff line number Diff line change
Expand Up @@ -1703,15 +1703,16 @@ function twig_array_reduce(Environment $env, $array, $arrow, $initial = null)
{
twig_check_arrow_in_sandbox($env, $arrow, 'reduce', 'filter');

if (!\is_array($array)) {
if (!$array instanceof \Traversable) {
throw new RuntimeError(sprintf('The "reduce" filter only works with arrays or "Traversable", got "%s" as first argument.', \gettype($array)));
}
if (!\is_array($array) && !$array instanceof \Traversable) {
throw new RuntimeError(sprintf('The "reduce" filter only works with arrays or "Traversable", got "%s" as first argument.', \gettype($array)));
}

$array = iterator_to_array($array);
$accumulator = $initial;
foreach ($array as $key => $value) {
$accumulator = $arrow($accumulator, $value, $key);
}

return array_reduce($array, $arrow, $initial);
return $accumulator;
}

function twig_array_some(Environment $env, $array, $arrow)
Expand Down
14 changes: 14 additions & 0 deletions tests/Fixtures/filters/reduce_key.test
Original file line number Diff line number Diff line change
@@ -0,0 +1,14 @@
--TEST--
"reduce" filter passes iterable key to callback
--TEMPLATE--
{% set status_classes = {
'success': 200,
'warning': 400,
'error': 500,
} %}

{{ status_classes|reduce((carry, v, k) => status_code >= v ? k : carry, '') }}
--DATA--
return ['status_code' => 404]
--EXPECT--
warning

0 comments on commit 609794c

Please sign in to comment.