Solution
This won't work in Twig as presented in the question (see why below). Instead, users
would need to be changed to an associative array (or "hash" in Twig terminology) with keys that aren't integers, and you'd have to insert a merge
inside a merge
to change the value:
{% set users = {
person0: {name: 'Bill', age: 25},
person1: {name: 'Tim', age: 30},
person2: {name: 'John', age: 32}
} %}
{% set users = users|merge({ person1: users.person1|merge({age: 1000}) }) %}
{% for key, user in users %}
{{ key }}: {{ user.name }}, {{ user.age }}<br>
{% endfor %}
...which now outputs:
person0: Bill, 25
person1: Tim, 1000
person2: John, 32
If you need to change the keys' integers dynamically, you will write it like this using Twig's attribute
function and using brackets:
{% set loopIndex = 1 %}
{% set users = users|merge({ ('person' ~ loopIndex): attribute(users, 'person' ~ loopIndex)|merge({age: 1000}) }) %}
The Reason Why the Question's Array Doesn't Work
Twig's merge
filter uses PHP's array_merge
function, and according to PHP's docs when using array_merge
:
If the input arrays have the same string keys, then the later value for that key will overwrite the previous one. If, however, the arrays contain numeric keys, the later value will not overwrite the original value, but will be appended.
So trying to overwrite an existing hash in the original array
{% set users = [
{name: 'Bill', age: 25},
{name: 'Tim', age: 30},
{name: 'John', age: 32}
] %}
...will just add the hash as a new, fourth item in the array, not replace the second one. To demonstrate this clearer, we can rewrite users
as a hash like this (it's considered the same as above):
{% set users = {
0: {name: 'Bill', age: 25},
1: {name: 'Tim', age: 30},
2: {name: 'John', age: 32}
} %}
By trying to target the key 1
to change its hash and output users
:
{% set users = users|merge([ users.1|merge({age: 1000}) ]) %}
{% for key, user in users %}
{{ key }}: {{ user.name }}, {{ user.age }}<br>
{% endfor %}
...we get this list:
0: Bill, 25
1: Tim, 30
2: John, 32
3: Tim, 1000
A new "Tim" user will get appended even if you make the keys strings like '0'
, '1'
, etc, or using Twig's attribute
function. An issue for this was posted in Twig's github and the conversation explains it some more. You can only change a value if it's an array with a list of single values (not a hash) or if it's a key/value hash, and the key can't be an integer.