【问题标题】:Filtering and splicing an array in Twig在 Twig 中过滤和拼接数组
【发布时间】:2017-01-17 16:49:13
【问题描述】:

我有一个用户记录数组(0 索引,来自数据库查询),每个记录都包含一个字段数组(按字段名称索引)。例如:

Array
(
    [0] => Array
        (
            [name] => Fred
            [age] => 42
        )

    [1] => Array
        (
            [name] => Alice
            [age] => 42
        )

    [2] => Array
        (
            [name] => Eve
            [age] => 24
        )

)

在我的 Twig 模板中,我想获取 age 字段为 42 的所有用户,然后将这些用户的 name 字段作为数组返回。然后我可以将该数组传递给join(<br>) 以每行打印一个名称。

例如,如果年龄是 42 岁,我希望 Twig 输出:

Fred<br>
Alice

这可以在 Twig 中开箱即用,还是我需要编写自定义过滤器?我不确定如何用几句话来描述我想要的东西,所以可能是其他人写了一个过滤器,但我无法通过搜索找到它。

【问题讨论】:

  • 正如在下面的答案中提到的那样,这并没有给我与join 相同的功能,因为它会将粘合字符串放在每个元素之后,而不是除最后一个元素之外的所有元素。

标签: php arrays twig silex


【解决方案1】:

最终解决方案结合了迄今为止发布的内容,并进行了一些更改。伪代码为:

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 只接受arrayTraversable 作为参数,因此您必须将user.name 字符串转换为单元素数组,方法是将其包含在[] 中。您还需要转义user.name 并使用raw,否则&amp;lt;br&amp;gt; 将转换为&amp;lt;br&amp;gt;(在这种情况下,我希望用户名转义,因为它来自不受信任的来源,而换行符是一个字符串我已经指定了)。

【讨论】:

    【解决方案2】:

    您可以在您申请循环的数组上应用过滤器,如下所示:

    {% for u in user|filter((u) => u.age == 42) -%}
       <!-- do your stuff -->
    {% endfor %}
    

    【讨论】:

      【解决方案3】:

      从 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 %}
      

      【讨论】:

        【解决方案4】:

        在 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)

        Twig Deprecated Features

        【讨论】:

        • 这不是所要求的,因为最后一行不应该有&lt;br&gt;
        【解决方案5】:
        {% 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 user in users if user.age == 42 %}来做这件事doc
        • 这不如join 优雅,因为我必须记住不要包含最后的粘合元素(我希望在除最后一个名称之外的每个名称之后都包含&lt;br&gt;),而loop.last 明确不包含t 有条件地工作。因为我不知道哪个元素会是最后一个,所以我不确定我可以通过这种方式解决我的问题吗?
        • 您的回答很好,但没有像这样&lt;/br&gt; 的标准。你最好使用&lt;br&gt;&lt;br/&gt; 而不是&lt;/br&gt;
        • 不幸的是,这不起作用,原因如下: 1. {% set aUserMatchingCreteria %} 无效(您必须使用 {% set aUserMatchingCreteria = [] %}) 2. 您可以使用带有字符串作为参数的 merge ,它必须是一个数组。[user.name] 就足够了。
        猜你喜欢
        • 2015-01-05
        • 1970-01-01
        • 2017-07-14
        • 1970-01-01
        • 2013-02-13
        • 2018-06-25
        • 2012-03-25
        • 1970-01-01
        • 2011-03-19
        相关资源
        最近更新 更多