async def do_groupby(environment, value, attribute): expr = filters.make_attrgetter(environment, attribute) return [ filters._GroupTuple(key, await auto_to_seq(values)) for key, values in filters.groupby( sorted(await auto_to_seq(value), key=expr), expr) ]
def test_grouper_repr(self): from jinja2.filters import _GroupTuple t = _GroupTuple('foo', [1, 2]) assert t.grouper == 'foo' assert t.list == [1, 2] assert repr(t) == "('foo', [1, 2])" assert str(t) == "('foo', [1, 2])"
def groupby(environment, value, attribute, reverse=False): """Like Jinja's builtin `groupby` filter, but allows reversed order.""" expr = make_attrgetter(environment, attribute) return [ _GroupTuple(key, list(values)) for key, values in itertools.groupby( sorted(value, key=expr, reverse=reverse), expr) ]
def groupbyandsort(value, attribute, reverse): attr = lambda x: getattr(x, attribute) grouped = [ _GroupTuple(key, list(values)) for key, values in groupby(sorted(value, key=attr), attr) ] return sorted(grouped, key=lambda x: len(x.list), reverse=reverse)
def do_groupby(environment, value, attribute, sort=True): expr = make_attrgetter(environment, attribute) # Original behavior: groups are sorted if sort: return [ _GroupTuple(key, list(values)) for key, values in groupby(sorted(value, key=expr), expr) ] # Added behavior: original order of appearance is kept all_groups = [expr(_) for _ in value] group_set = set() unique_groups = [] for group in all_groups: if group not in group_set: unique_groups.append(group) group_set.add(group) grouped = {k: list(v) for k, v in groupby(sorted(value, key=expr), expr)} return [_GroupTuple(group, grouped[group]) for group in unique_groups]
def groupby(value, attribute, full_alphabet=False): """Group alphabetically a sequence of objects by a common attribute.""" attr_getter = lambda item: first_letter(getattr(item, attribute)) grouped = _groupby(sorted(value, key=attr_getter), attr_getter) if full_alphabet: # convert grouped to dict grouped = dict(map(lambda group: (group[0], list(group[1])), grouped)) # prepare unique set of all used and alphabetic letters all_letters = sorted(set(grouped.keys() + list(alphabet()))) # return special tuples, empty list is used if there are no items # for given letter return [_GroupTuple( (letter, grouped.get(letter, [])) ) for letter in all_letters] return sorted(map(_GroupTuple, grouped))
def groupby(value, attribute, full_alphabet=False): """Group alphabetically a sequence of objects by a common attribute.""" attr_getter = lambda item: first_letter(getattr(item, attribute)) grouped = _groupby(sorted(value, key=attr_getter), attr_getter) if full_alphabet: # convert grouped to dict grouped = dict(map(lambda group: (group[0], list(group[1])), grouped)) # prepare unique set of all used and alphabetic letters all_letters = sorted(set(grouped.keys() + list(alphabet()))) # return special tuples, empty list is used if there are no items # for given letter return [ _GroupTuple((letter, grouped.get(letter, []))) for letter in all_letters ] return sorted(map(_GroupTuple, grouped))
def do_groupby(environment, value, attribute): """Group a sequence of objects by a common attribute. If you for example have a list of dicts or objects that represent persons with `gender`, `first_name` and `last_name` attributes and you want to group all users by genders you can do something like the following snippet: .. sourcecode:: html+jinja <ul> {% for group in persons|groupby('gender') %} <li>{{ group.grouper }}<ul> {% for person in group.list %} <li>{{ person.first_name }} {{ person.last_name }}</li> {% endfor %}</ul></li> {% endfor %} </ul> Additionally it's possible to use tuple unpacking for the grouper and list: .. sourcecode:: html+jinja <ul> {% for grouper, list in persons|groupby('gender') %} ... {% endfor %} </ul> As you can see the item we're grouping by is stored in the `grouper` attribute and the `list` contains all the objects that have this grouper in common. .. versionchanged:: 2.6 It's now possible to use dotted notation to group by the child attribute of another attribute. """ expr = make_attrgetter(environment, attribute, lambda val: '' if val is None else val) return [_GroupTuple(key, list(values)) for key, values in groupby(sorted(value, key=expr), expr)]
async def do_groupby(environment, value, attribute): expr = filters.make_attrgetter(environment, attribute) return [filters._GroupTuple(key, await auto_to_seq(values)) for key, values in filters.groupby(sorted( await auto_to_seq(value), key=expr), expr)]
def do_groupby_start(environment, value): return [ _GroupTuple(key, list(values)) for key, values in groupby(sorted(value, key=do_start), do_start) ]
def groupby(environment, value, attribute, reverse=False): """Like Jinja's builtin `groupby` filter, but allows reversed order.""" expr = make_attrgetter(environment, attribute) return [_GroupTuple(key, list(values)) for key, values in itertools.groupby(sorted(value, key=expr, reverse=reverse), expr)]