Example #1
0
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)
    ]
Example #2
0
 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])"
Example #3
0
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)
    ]
Example #4
0
 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])"
Example #5
0
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)
Example #6
0
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]
Example #7
0
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))
Example #8
0
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))
Example #9
0
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)]
Example #10
0
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)
    ]
Example #12
0
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)]