Reputation: 1275
In my case I have a list of dicts that contains other several list of dicts.
l = [{
'a': [
{ 'b': 4}
]
}, {
'a': [
{ 'b': 3}
]
}]
What I would technically like to do would be to sort using the path ['a'][0]['b'] using the sort filter of jinja2.
Is it possible in someway?
Upvotes: 2
Views: 4634
Reputation: 2655
You can use the attribute
parameter in sort
, where you specify 0
as the first element in the list then b
as the key of that element, and in your case you have attribute="a.0.b"
:
your_document_list = [{
'a': [
{ 'b': 4}
]
}, {
'a': [
{ 'b': 3}
]
}]
{% for document in your_document_list | sort(attribute="a.0.b") %}
...
{% endfor %
Upvotes: 2
Reputation: 12669
You can try this in one line if you want:
l = [{
'a': [
{ 'b': 4}
]
}, {
'a': [
{ 'b': 9}
]
},
{
'a': [
{ 'b': 3}
]
}]
print(sorted(l,key=lambda x:x['a'][0]['b']))
output:
[{'a': [{'b': 3}]}, {'a': [{'b': 4}]}, {'a': [{'b': 9}]}]
Explanation :
Using lambda you can access b's values , so basically sorted() will sort basis on a list of int here how:
print(list(map(lambda x:x['a'][0]['b'],l)))
output:
[4, 9, 3]
sorted() will sort basis on this list.
Upvotes: -1
Reputation: 552
You can write your custom template filter.
http://jinja.pocoo.org/docs/dev/api/#custom-filters
Here would be a rough solution (no support for reverse, case sensitive, etc.):
Somwhere in your app:
def deep_sort(value, attribute, subattribute):
return sorted(value, key=lambda element: element[attribute][0][subattribute])
environment.filters['deep_sort'] = deep_sort
And in your template:
{% for value in l|deep_sort('a', 'b') %}
{{value['a'][0]['b']}}
{% endfor %}
Upvotes: 4