Как удалить дублированные элементы в массиве на Twig
Как удалить дублированные элементы в массиве на Twig?
У меня есть значение массива в ветке, например.
{{ set array = ["testA","testB","testA","testC","testB"] }}
Я хочу удалить дублированные элементы и использовать только testA, testB, testC
{% for name in array%}
//skip the duplicate items and use only testA,testB,testC
{% endfor %}
Как я могу это сделать?
Ответы
Ответ 1
Twig - движок VIEW и не должен использоваться - в теории - для управления данными. Это (очень) хорошая практика для использования (предположительно) PHP для сбора данных, выполнения всех необходимых манипуляций, а затем передачи правильных данных в ваш вид.
Итак, вот как вы можете это сделать в чистом синтаксисе Twig:
{% set newArray = [] %}
{% for name in array %}
{% if name not in newArray %}
My name is {{name}}
{% set newArray = newArray|merge([name]) %}
{% endif %}
{% endfor %}
Ответ 2
В этом случае, как @Webberig сказал, что лучше подготовить свои данные до рендеринга представления. Но когда у вас есть более сложный процесс, и если это связано с представлением, вы можете создать расширение Twig, с расширением код будет выглядеть так:
MyTwigExtension.php
для версий Twig 1.12 и выше:
/**
* {@inheritdoc}
*/
public function getFunctions()
{
return array(
new \Twig_SimpleFunction('array_unset', array($this, 'arrayUnset'))
);
}
Если вы используете версию Twig раньше 1.12, вместо этого используйте MyTwigExtension.php
:
/**
* {@inheritdoc}
*/
public function getFunctions()
{
return array(
'array_unset' => new \Twig_Function_Method($this, 'arrayUnset')
);
}
/**
* Delete a key of an array
*
* @param array $array Source array
* @param string $key The key to remove
*
* @return array
*/
public function arrayUnset($array, $key)
{
unset($array[$key]);
return $array;
}
Twig:
{% set query = array_unset(query, 'array_key') %}
Ответ 3
Быстрый ответ (TL; DR)
- Пользовательский фильтр Twig
array_unique
позволяет удалить дубликаты
- Это может быть непосредственно перенесено из собственного PHP
Подробный ответ
Контекст
- Twig 2.x(последняя версия от Wed 2017-02-08)
- Альтернативный подход по сравнению с другими подходами, указанными в другом месте
Проблема
- Сценарий:
- DeloperSutasSugas хочет удалить массив
- Встроенная функция array_unique PHP может выполнять работу
Example01
- DeloperSutasSugas начинается с последовательно-индексированного массива
- преобразуется из
BEFORE
в AFTER
{%- set mylist = ['alpha','alpha','bravo','charlie','alpha','alpha','delta','echo'] -%}
BEFORE:
['alpha','alpha','bravo','charlie','alpha','alpha','delta','echo']
AFTER:
['alpha','bravo','charlie','delta','echo']
Решение
Пользовательский фильтр
[...]
// {"define_filter_":"array_unique" ,"desc":"PHP array_unique function" },
$filter = new Twig_SimpleFilter('array_unique', function ( $vinp=Array() ) {
$vout = ( $vinp );
$vout = array_unique( $vout );
$vout = array_values( $vout ); // PHP annoyance array reindex -- optional
return $vout;
});
$twig->addFilter($filter);
//;;
[...]
Вывод
{%- set mylist = mylist|array_unique -%}
Ловушки
- Требуется фильтр аддона (решение не работает с родным Twig)
См. также
Ответ 4
Для Symfony!
Сервис: app/config/service.yml
twig_array_unique_function:
class: AppBundle\Twig\ArrayUniqueFunction
tags:
- { name: twig.function }
Класс: src/AppBundle/Twig/ArrayUniqueFunction.php
<?php
namespace AppBundle\Twig;
class ArrayUniqueFunction extends \Twig_Extension
{
public function getFilters()
{
return [new \Twig_SimpleFilter('array_unique', 'array_unique')];
}
public function getFunctions()
{
return [new \Twig_SimpleFunction('array_unique', 'array_unique')];
}
}
Спасибо: https://github.com/getgrav/grav/blob/develop/system/src/Grav/Common/Twig/TwigExtension.php
Ответ 5
{% set keeper = {} %}
{% set throwaway = [] %}
{% for thing in yourSet.all() %}
{% if thing.id not in throwaway %}
{% set throwaway = throwaway|merge([thing.id]) %}
{% set keeper = keeper|merge([{ slug: thing.slug, title: thing.title}]) %}
{% endif %}
{% endfor %}
Модификация по принятому ответу выше. Мне нужно было удалить дубликаты из набора и получить объект только слаг и заголовок.
Ответ 6
Вы можете сделать это в одну строку, начиная с Twig 1.41 и 2.10:
{% set unique = array|reduce(
(unique, item) => item in unique ? unique : unique|merge([item]), []
) %}
В вашем примере:
{% for name in array|reduce((unique, item) => item in unique ? unique : unique|merge([item]), []) %}
My name is {{name}}
{% endfor %}
Ответ 7
Оператор in
выполняет тест на герметичность.
Возвращает true, если левый операнд содержится в правой части.
{% if name in array %}
http://twig.sensiolabs.org/doc/templates.html#containment-operator