Iterating through map in reverse
Since data is serialized to JSON using serde-json, when iterating over a map the implementation of the map defines the iteration order. serde-json uses a BTreeMap by default, where entries are sorted by key. This means that when iterating over a map using a for loop, the order is always by key.
It would be nice if a map could also be iterated in reverse. The reverse filter only supports arrays and strings though. I tried adding that functionality to the reverse filter (since that seems very natural to me from a user perspective), but since the filter simply returns a new map, that doesn't work (because it always becomes a BTreeMap in the end, which is sorted by key).
We could make serde-json use an insertion-order map by passing in the preserve_order feature, but I'm not sure if that's desired (and it might have undesired side effects).
In case reverse is the wrong place: Jinja provides a dictsort filter, but that would also require the preserve_order feature.
The third option would be to add a special syntax to the for loop, for example something like this:
{% for rev key, value in mymap %}
...
This would call .rev() on the iterator. However, I'm not sure if you want new syntax if filters could in theory achieve the same (with more flexibility, like custom sorting).
I don't think it makes sense in Tera though. Structs are represented as JSON objects, what does it mean to iterate on a dict in reverse in that case? By insertion order like you mentioned? Arrays/strings have some clear meaning for iteration in reverse, dict not so much.
The thing is that there still is a clearly defined iteration order:
- Without
preserve_orderfeature, the entries are iterated sorted alphanumerically by key - With
preserve_orderfeature, the entries are iterated sorted by insertion order (which probably means that serde will preserve the order of the original map)
I use BTreeMaps in my code precisely because I want to iterate sorted by key. Just because it gets converted to a JSON object doesn't mean that the order must be undefined. And if it's defined, it could be reversed :slightly_smiling_face:
I guess it should only be implemented if preserve_order is enabled then.