Twig循环分组

时间:2014-05-11 21:31:48

标签: group-by twig

假设我在数组中将一些名为“people”的数据转换为这样的树枝模板:

firstname | surname | colour
Fred        Smith     Blue
James       Holmes    Red
Sarah       Fisher    Blue
Chrstine    Jenkins   Yellow
Sid         Wells     Red
Cory        Simpson   Blue
Laura       Jones     Yellow

使用此数据,我需要通过“颜色”列对它们进行分组。通过基于颜色包裹用户周围的div。 e.g

<div class="colour_container">
Fred Smith - Blue<br>
Sarah Fisher - Blue<br>
Cory Simpson - Blue<br>
</div>

<div class="colour_container">
James Holmes - Red<br>
Sid Wells - Red<br>
</div> 

<div class="colour_container">
Christine Jenkins - Yellow<br>
Laura Jones - Yellow<br>
</div>

现在,如果我使用树枝循环,它会将div放在每个名称周围,而不是按颜色对它们进行分组。什么是获得上述输出的最简单方法?我已经在循环中尝试了各种各样的东西,但我很挣扎。

{% for p in people %}
   <div class="colour_container">
       {{ p.firstname }} {{ p.surname }} - {{ p.colour }}
   </div>
{% endfor %}

我需要它以某种方式循环遍历唯一的颜色值,然后循环遍历属于该颜色的名称。

6 个答案:

答案 0 :(得分:5)

我最近遇到过类似的问题。我做了扩展并将其作为开源发布。它引入了lambda表达式和|group_by过滤器。

https://github.com/dpolac/twig-lambda

你可以简单地写一下:

{% for colour, group in people|group_by(=> _.colour) %}
   <div class="colour_container">
       {% for person in group %}
           {{ person.firstname }} {{ person.surname }} - {{ person.colour }}
       {% endfor %}
   </div>
{% endfor %}

答案 1 :(得分:3)

首先,根据您的产品数组创建颜色列表:

$colors = array();
foreach ($people as $p)
{
  if (!in_array($p['colour'], $colors))
  {
    $colors[] = $p['colour'];
  }
}

// ...

$twig->render("view.html.twig", array(
    'colors' => $colors,
    'products' => $products
));

然后,迭代您的颜色,并显示与当前颜色匹配的产品:

{% for color in colors %}
   <div class="colour_container">
   {% for p in people %}
       {% if p.colour == color %}
         {{ p.firstname }} {{ p.surname }} - {{ p.colour }}<br/>
       {% endif %}
   {% endfor %}
   </div>
{% endfor %}

这应该会给你预期的结果。

答案 2 :(得分:2)

我不建议你这样做,因为在模板中完成所有工作感觉有点费力,但提出枝条解决方案非常有趣,所以无论如何我都做了一个回答你的问题。

{# create array of handled people so you don't have to loop through the all the people for each colour #}
{% set handledPeople = [] %}
{% for person in people if person not in handledPeople %}
    <div class="colour_container">
        {% for p in people if p.colour == person.colour and p not in handledPeople %}
            <p>{{ p.firstname }} {{ p.surname }} - {{ p.colour }}</p>
            {% set handledPeople = handledPeople|merge([p]) %}
        {% endfor %}
    </div>
{% endfor %}

答案 3 :(得分:2)

真的不是那么糟糕。我确实想避免多次运行for循环但是嘿嘿。我不知道你可以把一个for循环的条件分开(http://twig.sensiolabs.org/doc/tags/for.html)。因此我做了以下事情:

<div class="colour_container">
{% for p in people if p.colour == "Blue" %}
   {{ p.firstname }} {{ p.surname }} - {{ p.colour }}
{% endfor %}
</div>

<div class="colour_container">
{% for p in people if p.colour == "Red" %}
   {{ p.firstname }} {{ p.surname }} - {{ p.colour }}
{% endfor %}
</div>

<div class="colour_container">
{% for p in people if p.colour == "Green" %}
   {{ p.firstname }} {{ p.surname }} - {{ p.colour }}
{% endfor %}
</div>

因为我知道所有颜色的颜色,我只需要为每种颜色重复一次这样的颜色,然后它会起作用一种对待= D

答案 4 :(得分:0)

您可以使用批处理过滤器。

{% set items = ['a', 'b', 'c', 'd', 'e', 'f', 'g'] %}

<table>
{% for row in items|batch(3, 'No item') %}
    <tr>
        {% for column in row %}
            <td>{{ column }}</td>
        {% endfor %}
    </tr>
{% endfor %}
</table>

答案 5 :(得分:-1)

你好,这真的是你想要的:

{% set firstname=['Fred','James','Sarah','Chrstine','Sid','Cory','Laura'] %}
{% set surname=['Smith','Holmes','Fisher','Jenkins','Wells','Simpson','Jones'] %}
{% set colour=['Blue','Red','Blue','Yellow','Red','Blue','Yellow'] %}
<div class="colour_container">
{{ firstname[0]~' '~surname[0]~' '~colour[0] }}
<br>
{{ firstname[2]~' '~surname[2]~' '~colour[2] }}
<br>
{{ firstname[5]~' '~surname[5]~' '~colour[5] }}
<br>
</div>
<div class="colour_container">
{{ firstname[1]~' '~surname[1]~' '~colour[1] }}<br>
{{ firstname[4]~' '~surname[4]~' '~colour[4] }}
<br>
</div>
<div class="colour_container">
{{ firstname[3]~' '~surname[3]~' '~colour[3] }}<br>
{{ firstname[6]~' '~surname[6]~' '~colour[6] }}
<br>
</div>