You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

Twig渲染列表时如何校验已输出数据实现去重合并同项子元素

Twig支持通过模板内定义临时变量记录已输出内容实现去重,但这类分组聚合逻辑不建议放在模板层实现,优先在控制器层完成数据分组整理,模板只负责渲染即可,具体实现方案如下:

控制器层数据修正方案

你之前组装数据失败的原因是直接存入了getAdjustings()、getUnderActivities()返回的集合对象,没有展开遍历集合内的实体,也没有做分组、去重处理。按以下逻辑组装即可得到直接可用的嵌套结构:

// 初始化分组存储数组,键为adjusting名称,满足同名合并需求
$groupedAdjustings = [];

foreach ($activity->getUnderActivities() as $underActivity) {
    foreach ($underActivity->getIndications() as $indice) {
        // 提前匹配状态对应的样式类,PHP版本低于8.0可替换为if-else判断
        $statusClass = match($indice->getIndicationPostAdjusting()) {
            'Green' => 'text-success',
            'Orange' => 'text-warning',
            default => 'text-danger'
        };
        foreach ($indice->getAdjustings() as $adjusting) {
            if ($adjusting === null) {
                continue;
            }
            // 若存在同名但实际不同的adjusting,可将键替换为$adjusting->getId()避免误合并
            $adjKey = $adjusting->getName();
            // 分组不存在时初始化结构
            if (!isset($groupedAdjustings[$adjKey])) {
                $groupedAdjustings[$adjKey] = [
                    'name' => $adjusting->getName(),
                    'children' => []
                ];
            }
            // 子项去重:拼接唯一键避免重复子项挂载
            $childKey = $underActivity->getName() . '_' . $statusClass;
            if (!isset($groupedAdjustings[$adjKey]['children'][$childKey])) {
                $groupedAdjustings[$adjKey]['children'][$childKey] = [
                    'name' => $underActivity->getName(),
                    'class' => $statusClass
                ];
            }
        }
    }
}
// 重置children数组的索引,去掉去重用的自定义键
foreach ($groupedAdjustings as &$item) {
    $item['children'] = array_values($item['children']);
}
unset($item);

// 传入模板渲染
return $this->render('对应模板路径.html.twig', [
    'groupedAdjustings' => $groupedAdjustings,
    // 其余原有传入参数
]);
模板渲染代码

数据整理完成后,模板不需要多层嵌套循环和状态判断,直接遍历分组后的数据输出即可:

{% if groupedAdjustings is not empty %}
<ul>
    {% for adj in groupedAdjustings %}
    <li>{{ adj.name }}
        <ul>
            {% for child in adj.children %}
            <li class="{{ child.class }}">{{ child.name }}</li>
            {% endfor %}
        </ul>
    </li>
    {% endfor %}
</ul>
{% else %}
<p>Aucun aménagement n a été trouvée.</p>
{% endif %}
Twig原生去重实现(不推荐)

如果受场景限制无法修改后端逻辑,可直接在Twig中定义数组存储已渲染的项标识,判断未输出过再渲染对应内容:

{# 初始化存储已渲染项标识的数组 #}
{% set renderedAdj = [] %}
{% set renderedChild = [] %}
{% if activity.underActivities is not empty %}
<ul>
{% for underActivity in activity.underActivities %}
    {% for indice in underActivity.indications %}
        {% set statusClass = indice.indicationPostAdjusting == 'Green' ? 'text-success' : (indice.indicationPostAdjusting == 'Orange' ? 'text-warning' : 'text-danger') %}
        {% for adjusting in indice.adjustings %}
            {% if adjusting is not null %}
                {# 顶级项未渲染过时输出顶级项开头 #}
                {% if adjusting.name not in renderedAdj %}
                    {% set renderedAdj = renderedAdj|merge([adjusting.name]) %}
                    <li>{{ adjusting.name }}
                    <ul>
                {% endif %}
                    {# 子项未渲染过时输出子项 #}
                    {% set childKey = underActivity.name ~ '_' ~ adjusting.name %}
                    {% if childKey not in renderedChild %}
                        {% set renderedChild = renderedChild|merge([childKey]) %}
                        <li class="{{ statusClass }}">{{ underActivity.name }}</li>
                    {% endif %}
                {# 注意:该方案需要额外处理标签闭合、同组边界判断,维护成本极高,容易出现结构错误 #}
            {% endif %}
        {% endfor %}
    {% endfor %}
{% endfor %}
</ul>
{% else %}
<p>Aucun aménagement n a été trouvée.</p>
{% endif %}

注意:Twig层直接实现分组去重需要处理大量边界判断,标签闭合逻辑复杂,后续需求调整极易出现bug,生产环境优先选择后端提前分组的方案。

内容的提问来源于stack exchange,提问作者Noé Femeland

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.09.03 02:36:51