在 Twig 中过滤和拼接一个数组
Filtering and splicing an array in Twig
我有一个用户记录数组(0 索引,来自数据库查询),每个记录都包含一个字段数组(按字段名称索引)。例如:
Array
(
[0] => Array
(
[name] => Fred
[age] => 42
)
[1] => Array
(
[name] => Alice
[age] => 42
)
[2] => Array
(
[name] => Eve
[age] => 24
)
)
在我的 Twig 模板中,我想获取 age
字段为 42 的所有用户,然后 return 这些用户的 name
字段作为数组。然后我可以将该数组传递给 join(<br>)
以每行打印一个名称。
例如,如果年龄是 42,我希望 Twig 输出:
Fred<br>
Alice
这是否可以在 Twig 中开箱即用,或者我需要编写自定义过滤器吗?我不知道如何用几个词来描述我想要的,所以可能是别人写了一个过滤器,但我搜索找不到。
{% for user in users %}
{% if user.age == 42 %}
{{ user.name|e }}<br>
{% endif %}
{% endfor %}
或者,您可以创建一个元素数组
{% set aUserMatchingCreteria %}
{% for user in users %}
{% if user.age == 42 %}
{% aUserMatchingCreteria = aUserMatchingCreteria|merge(user.name) %}
{% endif %}
{% endfor %}
{{ aUserMatchingCreteria|join('<br>') }}
最终解决方案结合了迄今为止发布的内容,并进行了一些更改。伪代码是:
for each user
create empty array of matches
if current user matches criteria then
add user to matches array
join array of matches
树枝代码:
{% set matched_users = [] %}
{% for user in users %}
{% if user.age == 42 %}
{% set matched_users = matched_users|merge([user.name|e]) %}
{% endif %}
{% endfor %}
{{ matched_users|join('<br>')|raw }}
merge
将只接受 array
或 Traversable
作为参数,因此您必须通过包含将 user.name
字符串转换为 single-element 数组它在 []
。您还需要转义 user.name
并使用 raw
,否则 <br>
将被转换为 <br>
(在这种情况下,我希望用户名转义,因为它来自不受信任的来源,而换行符是我指定的字符串)。
在 twig 中,您可以将 for ( .... in ....) 与 if 条件合并,例如:
{% for user in users if user.age == 42 %}
{{ user.name }}{{ !loop.last ? '<br>' }}
{% endfor %}
编辑:此语法已弃用,建议我们使用 |filter
替代 for...if
语法。
Twig Filter: filter(过滤器名称为filter)
您可以在循环应用的数组上应用过滤器,如下所示:
{% for u in user|filter((u) => u.age == 42) -%}
<!-- do your stuff -->
{% endfor %}
从 Twig 2.10 开始,有条件地排除数组元素的推荐方法是 the filter
filter。正如在之前的一些回答中指出的那样,loop.last
有一些问题,但您可以简单地翻转逻辑并使用 loop.first
,它将始终如一地工作:
{% for user in users|filter((u) => u.age == 42) %}
{{ loop.first ?: '<br/>' }}
{{ user.name|e }}
{% endfor %}
我有一个用户记录数组(0 索引,来自数据库查询),每个记录都包含一个字段数组(按字段名称索引)。例如:
Array
(
[0] => Array
(
[name] => Fred
[age] => 42
)
[1] => Array
(
[name] => Alice
[age] => 42
)
[2] => Array
(
[name] => Eve
[age] => 24
)
)
在我的 Twig 模板中,我想获取 age
字段为 42 的所有用户,然后 return 这些用户的 name
字段作为数组。然后我可以将该数组传递给 join(<br>)
以每行打印一个名称。
例如,如果年龄是 42,我希望 Twig 输出:
Fred<br>
Alice
这是否可以在 Twig 中开箱即用,或者我需要编写自定义过滤器吗?我不知道如何用几个词来描述我想要的,所以可能是别人写了一个过滤器,但我搜索找不到。
{% for user in users %}
{% if user.age == 42 %}
{{ user.name|e }}<br>
{% endif %}
{% endfor %}
或者,您可以创建一个元素数组
{% set aUserMatchingCreteria %}
{% for user in users %}
{% if user.age == 42 %}
{% aUserMatchingCreteria = aUserMatchingCreteria|merge(user.name) %}
{% endif %}
{% endfor %}
{{ aUserMatchingCreteria|join('<br>') }}
最终解决方案结合了迄今为止发布的内容,并进行了一些更改。伪代码是:
for each user
create empty array of matches
if current user matches criteria then
add user to matches array
join array of matches
树枝代码:
{% set matched_users = [] %}
{% for user in users %}
{% if user.age == 42 %}
{% set matched_users = matched_users|merge([user.name|e]) %}
{% endif %}
{% endfor %}
{{ matched_users|join('<br>')|raw }}
merge
将只接受 array
或 Traversable
作为参数,因此您必须通过包含将 user.name
字符串转换为 single-element 数组它在 []
。您还需要转义 user.name
并使用 raw
,否则 <br>
将被转换为 <br>
(在这种情况下,我希望用户名转义,因为它来自不受信任的来源,而换行符是我指定的字符串)。
在 twig 中,您可以将 for ( .... in ....) 与 if 条件合并,例如:
{% for user in users if user.age == 42 %}
{{ user.name }}{{ !loop.last ? '<br>' }}
{% endfor %}
编辑:此语法已弃用,建议我们使用 |filter
替代 for...if
语法。
Twig Filter: filter(过滤器名称为filter)
您可以在循环应用的数组上应用过滤器,如下所示:
{% for u in user|filter((u) => u.age == 42) -%}
<!-- do your stuff -->
{% endfor %}
从 Twig 2.10 开始,有条件地排除数组元素的推荐方法是 the filter
filter。正如在之前的一些回答中指出的那样,loop.last
有一些问题,但您可以简单地翻转逻辑并使用 loop.first
,它将始终如一地工作:
{% for user in users|filter((u) => u.age == 42) %}
{{ loop.first ?: '<br/>' }}
{{ user.name|e }}
{% endfor %}