diff --git a/doc/filters/filter.rst b/doc/filters/filter.rst index 5c236eff0..a6c1c132d 100644 --- a/doc/filters/filter.rst +++ b/doc/filters/filter.rst @@ -29,6 +29,15 @@ function. The arrow function receives the value of the sequence or mapping: {% endfor %} {# output l = 40 xl = 42 #} +The arrow function also receives the key as a second argument: + +.. code-block:: twig + + {% for k, v in sizes|filter((v, k) => v > 38 and k != "xl") -%} + {{ k }} = {{ v }} + {% endfor %} + {# output l = 40 #} + Note that the arrow function has access to the current context. Arguments diff --git a/doc/filters/map.rst b/doc/filters/map.rst index 106b87463..b4849a629 100644 --- a/doc/filters/map.rst +++ b/doc/filters/map.rst @@ -17,6 +17,18 @@ mapping. The arrow function receives the value of the sequence or mapping: {{ people|map(p => "#{p.first} #{p.last}")|join(', ') }} {# outputs Bob Smith, Alice Dupond #} +The arrow function also receives the key as a second argument: + +.. code-block:: twig + + {% set people = { + "Bob": "Smith", + "Alice": "Dupond", + } %} + + {{ people|map((first, last) => "#{first} #{last}")|join(', ') }} + {# outputs Bob Smith, Alice Dupond #} + Note that the arrow function has access to the current context. Arguments diff --git a/src/Extension/CoreExtension.php b/src/Extension/CoreExtension.php index ae5d280bd..700f13bd9 100644 --- a/src/Extension/CoreExtension.php +++ b/src/Extension/CoreExtension.php @@ -1689,6 +1689,10 @@ function twig_array_batch($items, $size, $fill = null, $preserveKeys = true) function twig_array_filter($array, $arrow) { if (\is_array($array)) { + if (\PHP_VERSION_ID >= 50600) { + return array_filter($array, $arrow, \ARRAY_FILTER_USE_BOTH); + } + return array_filter($array, $arrow); } @@ -1697,11 +1701,12 @@ function twig_array_filter($array, $arrow) function twig_array_map($array, $arrow) { - if (!\is_array($array)) { - $array = iterator_to_array($array); + $r = []; + foreach ($array as $k => $v) { + $r[$k] = $arrow($v, $k); } - return array_map($arrow, $array); + return $r; } function twig_array_reduce($array, $arrow, $initial = null) diff --git a/test/Twig/Tests/Fixtures/filters/filter.test b/test/Twig/Tests/Fixtures/filters/filter.test index 5a040faba..1d6a96be2 100644 --- a/test/Twig/Tests/Fixtures/filters/filter.test +++ b/test/Twig/Tests/Fixtures/filters/filter.test @@ -7,7 +7,7 @@ {{ k }} = {{ v }} {% endfor %} -{% for k, v in {a: 1, b: 2, c: 5, d: 2}|filter((v) => v > offset) -%} +{% for k, v in {a: 1, b: 2, c: 5, d: 8}|filter(v => v > offset) -%} {{ k }} = {{ v }} {% endfor %} @@ -19,16 +19,18 @@ {{ k }} = {{ v }} {% endfor %} --DATA-- -return ['it' => new \ArrayIterator(['a' => 1, 'b' => 2, 'c' => 5, 'd' => 2])] +return ['it' => new \ArrayIterator(['a' => 1, 'b' => 2, 'c' => 5, 'd' => 8])] --EXPECT-- 1 = 5 3 = 4 4 = 5 c = 5 +d = 8 1 = 5 3 = 4 4 = 5 c = 5 +d = 8 diff --git a/test/Twig/Tests/Fixtures/filters/filter_php_56.test b/test/Twig/Tests/Fixtures/filters/filter_php_56.test new file mode 100644 index 000000000..05711e981 --- /dev/null +++ b/test/Twig/Tests/Fixtures/filters/filter_php_56.test @@ -0,0 +1,20 @@ +--TEST-- +"filter" filter (PHP 5.6 required) +--CONDITION-- +version_compare(phpversion(), '5.6.0', '>=') +--TEMPLATE-- +{% set offset = 3 %} + +{% for k, v in {a: 1, b: 2, c: 5, d: 8}|filter((v, k) => (v > offset) and (k != "d")) -%} + {{ k }} = {{ v }} +{% endfor %} + +{% for k, v in it|filter((v, k) => (v > offset) and (k != "d")) -%} + {{ k }} = {{ v }} +{% endfor %} +--DATA-- +return ['it' => new \ArrayIterator(['a' => 1, 'b' => 2, 'c' => 5, 'd' => 8])] +--EXPECT-- +c = 5 + +c = 5 diff --git a/test/Twig/Tests/Fixtures/filters/map.test b/test/Twig/Tests/Fixtures/filters/map.test index 302ff5d2c..5552f8166 100644 --- a/test/Twig/Tests/Fixtures/filters/map.test +++ b/test/Twig/Tests/Fixtures/filters/map.test @@ -11,6 +11,10 @@ {{ k }} = {{ v }} {% endfor %} +{% for k, v in {a: 1, b: 2}|map((item, k) => item ~ "*" ~ k ) -%} + {{ k }} = {{ v }} +{% endfor %} + {% for k, v in [1, 2]|map(item => item + 2 ) -%} {{ k }} = {{ v }} {% endfor %} @@ -27,6 +31,9 @@ return ['it' => new \ArrayIterator([1, 2])] a = 1* b = 2* +a = 1*a +b = 2*b + 0 = 3 1 = 4