Example #1
0
def pluck(collection, path):
    """Retrieves the value of a specified property from all elements in the
    collection.

    Args:
        collection (list): List of dicts.
        path (str|list): Collection's path to pluck

    Returns:
        list: Plucked list.

    Example:

        >>> pluck([{'a': 1, 'b': 2}, {'a': 3, 'b': 4}, {'a': 5, 'b': 6}], 'a')
        [1, 3, 5]
        >>> pluck([[[0, 1]], [[2, 3]], [[4, 5]]], '0.1')
        [1, 3, 5]
        >>> pluck([{'a': {'b': 1}}, {'a': {'b': 2}}], 'a.b')
        [1, 2]
        >>> pluck([{'a': {'b': [0, 1]}}, {'a': {'b': [2, 3]}}], 'a.b.1')
        [1, 3]
        >>> pluck([{'a': {'b': [0, 1]}}, {'a': {'b': [2, 3]}}], ['a', 'b', 1])
        [1, 3]

    .. versionadded:: 1.0.0

    .. versionchanged:: 4.0.0
        Function removed.

    .. versionchanged:: 4.0.1
        Made property access deep.
    """
    return map_(collection, pyd.property_(path))
Example #2
0
def pluck(collection, path):
    """Retrieves the value of a specified property from all elements in the
    collection.

    Args:
        collection (list): List of dicts.
        path (str|list): Collection's path to pluck

    Returns:
        list: Plucked list.

    Example:

        >>> pluck([{'a': 1, 'b': 2}, {'a': 3, 'b': 4}, {'a': 5, 'b': 6}], 'a')
        [1, 3, 5]
        >>> pluck([[[0, 1]], [[2, 3]], [[4, 5]]], '0.1')
        [1, 3, 5]
        >>> pluck([{'a': {'b': 1}}, {'a': {'b': 2}}], 'a.b')
        [1, 2]
        >>> pluck([{'a': {'b': [0, 1]}}, {'a': {'b': [2, 3]}}], 'a.b.1')
        [1, 3]
        >>> pluck([{'a': {'b': [0, 1]}}, {'a': {'b': [2, 3]}}], ['a', 'b', 1])
        [1, 3]

    .. versionadded:: 1.0.0

    .. versionchanged:: 4.0.0
        Function removed.

    .. versionchanged:: 4.0.1
        Made property access deep.
    """
    return map_(collection, pyd.property_(path))
Example #3
0
def properties(*paths):
    """Like :func:`property_` except that it returns a list of values at each
    path in `paths`.

    Args:
        *path (str|list): Path values to fetch from object.

    Returns:
        function: Function that returns object's path value.

    Example:

        >>> getter = properties('a', 'b', ['c', 'd', 'e'])
        >>> getter({'a': 1, 'b': 2, 'c': {'d': {'e': 3}}})
        [1, 2, 3]

    .. versionadded:: 4.1.0
    """
    return lambda obj: [getter(obj)
                        for getter in (pyd.property_(path) for path in paths)]
Example #4
0
def properties(*paths):
    """Like :func:`property_` except that it returns a list of values at each
    path in `paths`.

    Args:
        *path (str|list): Path values to fetch from object.

    Returns:
        function: Function that returns object's path value.

    Example:

        >>> getter = properties('a', 'b', ['c', 'd', 'e'])
        >>> getter({'a': 1, 'b': 2, 'c': {'d': {'e': 3}}})
        [1, 2, 3]

    .. versionadded:: 4.1.0
    """
    return lambda obj: [getter(obj)
                        for getter in (pyd.property_(path) for path in paths)]
Example #5
0
def order_by(collection, keys, orders=None, reverse=False):
    """This method is like :func:`sort_by` except that it sorts by key names
    instead of an iteratee function. Keys can be sorted in descending order by
    prepending a ``"-"`` to the key name (e.g. ``"name"`` would become
    ``"-name"``) or by passing a list of boolean sort options via `orders`
    where ``True`` is ascending and ``False`` is descending.

    Args:
        collection (list|dict): Collection to iterate over.
        keys (list): List of keys to sort by. By default, keys will be sorted
            in ascending order. To sort a key in descending order, prepend a
            ``"-"`` to the key name. For example, to sort the key value for
            ``"name"`` in descending order, use ``"-name"``.
        orders (list, optional): List of boolean sort orders to apply for each
            key. ``True`` corresponds to ascending order while ``False`` is
            descending. Defaults to ``None``.
        reverse (bool, optional): Whether to reverse the sort. Defaults to
            ``False``.

    Returns:
        list: Sorted list.

    Example:

        >>> items = [{'a': 2, 'b': 1}, {'a': 3, 'b': 2}, {'a': 1, 'b': 3}]
        >>> results = order_by(items, ['b', 'a'])
        >>> assert results == [{'a': 2, 'b': 1},\
                               {'a': 3, 'b': 2},\
                               {'a': 1, 'b': 3}]
        >>> results = order_by(items, ['a', 'b'])
        >>> assert results == [{'a': 1, 'b': 3},\
                               {'a': 2, 'b': 1},\
                               {'a': 3, 'b': 2}]
        >>> results = order_by(items, ['-a', 'b'])
        >>> assert results == [{'a': 3, 'b': 2},\
                               {'a': 2, 'b': 1},\
                               {'a': 1, 'b': 3}]
        >>> results = order_by(items, ['a', 'b'], [False, True])
        >>> assert results == [{'a': 3, 'b': 2},\
                               {'a': 2, 'b': 1},\
                               {'a': 1, 'b': 3}]

    .. versionadded:: 3.0.0

    .. versionchanged:: 3.2.0
        Added `orders` argument.

    .. versionchanged:: 3.2.0
        Added :func:`sort_by_order` as alias.

    .. versionchanged:: 4.0.0
        Renamed from ``order_by`` to ``order_by`` and removed alias
        ``sort_by_order``.
    """
    if isinstance(collection, dict):
        collection = collection.values()

    # Maintain backwards compatibility.
    if pyd.is_boolean(orders):
        reverse = orders
        orders = None

    comparers = []

    if orders:
        for i, key in enumerate(keys):
            if pyd.has(orders, i):
                order = 1 if orders[i] else -1
            else:
                order = 1

            comparers.append((pyd.property_(key), order))
    else:
        for key in keys:
            if key.startswith('-'):
                order = -1
                key = key[1:]
            else:
                order = 1

            comparers.append((pyd.property_(key), order))

    def comparison(left, right):
        # pylint: disable=useless-else-on-loop,missing-docstring
        for func, mult in comparers:
            result = _cmp(func(left), func(right))
            if result:
                return mult * result
        else:
            return 0

    return sorted(collection, key=cmp_to_key(comparison), reverse=reverse)
Example #6
0
def test_property_(case, arg, expected):
    assert _.map_(arg, _.property_(case)) == expected
Example #7
0
def order_by(collection, keys, orders=None, reverse=False):
    """This method is like :func:`sort_by` except that it sorts by key names
    instead of an iteratee function. Keys can be sorted in descending order by
    prepending a ``"-"`` to the key name (e.g. ``"name"`` would become
    ``"-name"``) or by passing a list of boolean sort options via `orders`
    where ``True`` is ascending and ``False`` is descending.

    Args:
        collection (list|dict): Collection to iterate over.
        keys (list): List of keys to sort by. By default, keys will be sorted
            in ascending order. To sort a key in descending order, prepend a
            ``"-"`` to the key name. For example, to sort the key value for
            ``"name"`` in descending order, use ``"-name"``.
        orders (list, optional): List of boolean sort orders to apply for each
            key. ``True`` corresponds to ascending order while ``False`` is
            descending. Defaults to ``None``.
        reverse (bool, optional): Whether to reverse the sort. Defaults to
            ``False``.

    Returns:
        list: Sorted list.

    Example:

        >>> items = [{'a': 2, 'b': 1}, {'a': 3, 'b': 2}, {'a': 1, 'b': 3}]
        >>> results = order_by(items, ['b', 'a'])
        >>> assert results == [{'a': 2, 'b': 1},\
                               {'a': 3, 'b': 2},\
                               {'a': 1, 'b': 3}]
        >>> results = order_by(items, ['a', 'b'])
        >>> assert results == [{'a': 1, 'b': 3},\
                               {'a': 2, 'b': 1},\
                               {'a': 3, 'b': 2}]
        >>> results = order_by(items, ['-a', 'b'])
        >>> assert results == [{'a': 3, 'b': 2},\
                               {'a': 2, 'b': 1},\
                               {'a': 1, 'b': 3}]
        >>> results = order_by(items, ['a', 'b'], [False, True])
        >>> assert results == [{'a': 3, 'b': 2},\
                               {'a': 2, 'b': 1},\
                               {'a': 1, 'b': 3}]

    .. versionadded:: 3.0.0

    .. versionchanged:: 3.2.0
        Added `orders` argument.

    .. versionchanged:: 3.2.0
        Added :func:`sort_by_order` as alias.

    .. versionchanged:: 4.0.0
        Renamed from ``order_by`` to ``order_by`` and removed alias
        ``sort_by_order``.
    """
    if isinstance(collection, dict):
        collection = collection.values()

    # Maintain backwards compatibility.
    if pyd.is_boolean(orders):
        reverse = orders
        orders = None

    comparers = []

    if orders:
        for i, key in enumerate(keys):
            if pyd.has(orders, i):
                order = 1 if orders[i] else -1
            else:
                order = 1

            comparers.append((pyd.property_(key), order))
    else:
        for key in keys:
            if key.startswith('-'):
                order = -1
                key = key[1:]
            else:
                order = 1

            comparers.append((pyd.property_(key), order))

    def comparison(left, right):
        # pylint: disable=useless-else-on-loop,missing-docstring
        for func, mult in comparers:
            result = _cmp(func(left), func(right))
            if result:
                return mult * result
        else:
            return 0

    return sorted(collection, key=cmp_to_key(comparison), reverse=reverse)