How to map scalar twig filter to array
Asked Answered
E

3

8

I have a simple array of floats. And I need to show it as comma separated string.

{{ arr|join(', ') }}

is bad solution because of excessive insignificant accuracy.

{% for val in arr %}
    {{val|number_format(2)}},
{% endfor %}

is bad because of extra comma at the end.

I would like to do something like this:

{{ arr|map(number_format(3))|join(', ') }}

but I have not found filter map or similar filter it Twig. Аnd I don't know how to implement such filter.

Emlen answered 24/10, 2016 at 17:14 Comment(1)
You can add existing functions to twigVelarde
S
7

Quick Answer (TL;DR)

Detailed Answer

Context

  • Twig 2.x (latest version as of Wed 2017-02-08)

Problem

  • Scenario: DeveloperGarricSugas wishes to apply higher-order function(s) to a Twig variable
    • Higher order functions allow any of various transformations on any Twig variable
  • Twig support for higher-order functions is limited
  • Nevertheless, there exist addon libraries for this
  • Custom filters or functions can also be used to simulate this

Example

  • DeveloperGarricSugas starts with a sequentially-indexed array
  • transform from BEFORE into AFTER (uppercase first letter)
{%- set mylist = ['alpha','bravo','charlie','delta','echo']  -%}

BEFORE: 
['alpha','bravo','charlie','delta','echo']

AFTER: 
['Alpha','Bravo','Charlie','Delta','Echo']

Solution

{%- set mylist = mylist|map(=> _|capitalize)  -%}    

Pitfalls

  • Twig higher-order functions limited support comes from addon-libraries
  • The above solution does not work with native Twig

See also

Solidago answered 8/2, 2017 at 20:9 Comment(2)
Please correct syntax: mylist|map(=> _|capitalize)Emlen
It looks as though there is now a version of map, with slightly different syntax, in Twig core. symfony.com/blog/twig-adds-filter-map-and-reduce-featuresTahoe
B
8

Why not use the loop variable?

{% for val in arr %}
    {{val|number_format(2)}}
    {% if not loop.last %}, {% endif %}
{% endfor %}
Bacchus answered 24/10, 2016 at 17:59 Comment(2)
OK, this is the solution for my example. But this is not a solution for the subject topic. You prefer to write a new analogue of an existing filter join... But can't we use the standard join filter for this?Emlen
You can write a new filter to use array_map under the hood, but join has no such functionality.Bacchus
S
7

Quick Answer (TL;DR)

Detailed Answer

Context

  • Twig 2.x (latest version as of Wed 2017-02-08)

Problem

  • Scenario: DeveloperGarricSugas wishes to apply higher-order function(s) to a Twig variable
    • Higher order functions allow any of various transformations on any Twig variable
  • Twig support for higher-order functions is limited
  • Nevertheless, there exist addon libraries for this
  • Custom filters or functions can also be used to simulate this

Example

  • DeveloperGarricSugas starts with a sequentially-indexed array
  • transform from BEFORE into AFTER (uppercase first letter)
{%- set mylist = ['alpha','bravo','charlie','delta','echo']  -%}

BEFORE: 
['alpha','bravo','charlie','delta','echo']

AFTER: 
['Alpha','Bravo','Charlie','Delta','Echo']

Solution

{%- set mylist = mylist|map(=> _|capitalize)  -%}    

Pitfalls

  • Twig higher-order functions limited support comes from addon-libraries
  • The above solution does not work with native Twig

See also

Solidago answered 8/2, 2017 at 20:9 Comment(2)
Please correct syntax: mylist|map(=> _|capitalize)Emlen
It looks as though there is now a version of map, with slightly different syntax, in Twig core. symfony.com/blog/twig-adds-filter-map-and-reduce-featuresTahoe
S
1

Quick Answer (TL;DR)

  • alternate approach is to use Twig loops (workaround)

Workaround

{%- set aaold = [1.234,234.56,11.222,22.333]  -%}
{%- set aanew = []  -%}
{% for item in aaold -%}
  {{ aanew|merge(item|number_format(3)) }}
{% endfor %}
{{ aanew | join(', ') }}

Pitfalls

  • requires use of array|merge
    • alternative to array|merge ... loop.first or loop.last as specified here
  • requires addition of loop control structure that means extra code bloat
Solidago answered 10/2, 2017 at 1:19 Comment(0)

© 2022 - 2024 — McMap. All rights reserved.