heapOverflow
heapOverflow

Reputation: 1275

Is it possible to sort a list of objects in Jinja2 based on subattributes?

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

Answers (3)

Jean Monet
Jean Monet

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

Aaditya Ura
Aaditya Ura

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

dVeza
dVeza

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

Related Questions