2013-07-13 35 views
0

看起來,您無法將排序列表分組到神廟中,而不會丟失排序順序。Jinja中的分組排序列表

下面的示例模板:

{% set l = [{'c': 3, 'result': 1.0}, 
      {'c': 3, 'result': 2.0}, 
      {'c': 9, 'result': 3.0}, 
      {'c': 1, 'result': 4.0}] %} 
{% for d in l|groupby('c') %} 
    {{d}} 
{% endfor %} 

不幸的是,這個模板輸出:

(1, [{'c': 1, 'result': 4.0}]) 
(3, [{'c': 3, 'result': 1.0}, {'c': 3, 'result': 2.0}]) 
(9, [{'c': 9, 'result': 3.0}]) 

但我所期待的是:

(3, [{'c': 3, 'result': 1.0}, {'c': 3, 'result': 2.0}]) 
(9, [{'c': 9, 'result': 3.0}]) 
(1, [{'c': 1, 'result': 4.0}]) 

我絕對保持項目按預先排序的順序排列。

有沒有人知道如何實現這一目標?

+0

結果穿過'sorted':https://github.com/mitsuhiko/jinja2 /blob/8261473c68993cbbf3460351a1a75be2a04ab245/jinja2/filters.py#L663-L702 – Blender

回答

0

正如@Blender在他的評論中指出的,jinja使用sorted根據收到的密鑰對傳遞的列表進行排序。

如果你想保持排序順序,恐怕唯一的解決辦法是編寫你自己的忍者過濾器。

這裏我實現了過濾器來實現這一點:

from jinja2 import environmentfilter 
from itertools import groupby 
from jinja2.filters import make_attrgetter, _GroupTuple 
@environmentfilter 
def do_groupby(environment, value, attribute): 
    expr = make_attrgetter(environment, attribute) 
    return map(_GroupTuple, groupby(value, expr)) 

注意:如果接收到的列表是分組正確(該組指標必須按順序)該濾波器僅工作。該列表,例如不正確組:

[{'c': 3, 'result': 1.0}, 
{'c': 9, 'result': 2.0}, 
{'c': 3, 'result': 3.0}, 
{'c': 1, 'result': 4.0}] 
1

更新到最新版本神社:

import jinja2 

from jinja2 import environmentfilter 
from itertools import groupby 
from jinja2.filters import make_attrgetter, _GroupTuple 

@environmentfilter 
def do_sorted_groupby(environment, value, attribute): 
    expr = make_attrgetter(environment, attribute) 
    return [_GroupTuple(key, list(values)) for key, values 
      in groupby(value, expr)] 

env = jinja2.Environment() 
env.filters['sorted_groupby'] = do_sorted_groupby 

ret = env.from_string(''' 
{% set l = [{'c': 3, 'result': 1.0}, 
      {'c': 3, 'result': 2.0}, 
      {'c': 9, 'result': 3.0}, 
      {'c': 1, 'result': 4.0}] %} 
{% for d in l|sorted_groupby('c') %} 
    {{d}} 
{% endfor %} 
''').render() 

print(ret)