Add shuffle filter

This commit is contained in:
sarah-eit
2024-01-19 11:33:56 +01:00
committed by Fabien Potencier
parent b37417972c
commit 17430ae5ac
3 changed files with 136 additions and 0 deletions
+89
View File
@@ -0,0 +1,89 @@
``shuffle``
===========
The ``shuffle`` filter shuffles a sequence, a mapping, or a string:
.. code-block:: twig
{% for user in users|shuffle %}
...
{% endfor %}
.. caution::
The shuffled array does not preserve keys. So if the input had not sequential keys
but indexed keys (using the user id for instance),
it is not the case anymore after shuffling it.
Example 1:
.. code-block:: html+twig
{% set items = [
'a',
'b',
'c',
] %}
<ul>
{% for item in items|shuffle %}
<li>{{ item }}</li>
{% endfor %}
</ul>
The above example will be rendered as:
.. code-block:: html
<ul>
<li>a</li>
<li>c</li>
<li>b</li>
</ul>
Note, results can also be :
"a, b, c" or "b, a, c" or "b, c, a" or "c, a, b" or "c, b, a".
Example 2:
.. code-block:: html+twig
{% set items = {
'a': 'd',
'b': 'e',
'c': 'f',
} %}
<ul>
{% for index, item in items|shuffle %}
<li>{{ index }} - {{ item }}</li>
{% endfor %}
</ul>
The above example will be rendered as:
.. code-block:: html
<ul>
<li>0 - d</li>
<li>1 - f</li>
<li>2 - e</li>
</ul>
Note, results can also be :
"d, e, f" or "e, d, f" or "e, f, d" or "f, d, e" or "f, e, d".
.. code-block:: html+twig
{% set string = 'ghi' %}
<p>{{ string|shuffle }}</p>
The above example will be rendered as:
.. code-block:: html
<p>gih</p>
Note, results can also be :
"ghi" or "hgi" or "hig" or "igh" or "ihg".
+31
View File
@@ -221,6 +221,7 @@ final class CoreExtension extends AbstractExtension
// string/array filters
new TwigFilter('reverse', [self::class, 'reverse'], ['needs_charset' => true]),
new TwigFilter('shuffle', [self::class, 'shuffle'], ['needs_charset' => true]),
new TwigFilter('length', [self::class, 'length'], ['needs_charset' => true]),
new TwigFilter('slice', [self::class, 'slice'], ['needs_charset' => true]),
new TwigFilter('first', [self::class, 'first'], ['needs_charset' => true]),
@@ -897,6 +898,36 @@ final class CoreExtension extends AbstractExtension
return $string;
}
/**
* Shuffles an array, a \Traversable instance, or a string.
* The function does not preserve keys.
*
* @internal
*/
public static function shuffle(string $charset, array|\Traversable|string|null $item): mixed
{
if (\is_string($item)) {
if ('UTF-8' !== $charset) {
$item = self::convertEncoding($item, 'UTF-8', $charset);
}
$item = preg_split('/(?<!^)(?!$)/u', $item, -1);
shuffle($item);
$item = implode('', $item);
if ('UTF-8' !== $charset) {
$item = self::convertEncoding($item, $charset, 'UTF-8');
}
}
if ($item instanceof \Traversable || \is_array($item)) {
$item = self::toArray($item, false);
shuffle($item);
}
return $item;
}
/**
* Sorts an array.
*
+16
View File
@@ -0,0 +1,16 @@
--TEST--
"shuffle" filter
--TEMPLATE--
{{ 'bar'|shuffle|length }}
{{ [3, 1]|shuffle|join()|length }}
{{ ['foo', 'bar']|shuffle|join()|length }}
{{ {'a': 'd', 'b': 'e', 'c': 'f'}|shuffle|join()|length }}
{{ traversable|shuffle|join|length }}
--DATA--
return ['traversable' => new \ArrayObject([0 => 3, 1 => 2, 2 => 1])]
--EXPECT--
3
2
6
3
3