Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
1 change: 1 addition & 0 deletions CHANGELOG.rst
Original file line number Diff line number Diff line change
Expand Up @@ -6,6 +6,7 @@ Changelog
Unreleased
----------

- Stop consuming iterables in ``nth`` once a nonnegative index has been reached.
- Transliterate letters like ``ß``, ``æ``, ``ø`` and ``Ł`` in ``slugify`` through ``deburr`` instead of
dropping them.
- Search values in generic mappings with ``includes`` and respect the start offset.
Expand Down
4 changes: 3 additions & 1 deletion src/pydash/arrays.py
Original file line number Diff line number Diff line change
Expand Up @@ -1216,12 +1216,14 @@ def nth(array: t.Iterable[T], pos: int = 0) -> t.Union[T, None]:
.. versionchanged:: VERSION
Support iterables that are not sequences, such as generators and sets.
They previously returned ``None``.
For a nonnegative index, iteration stops once the requested element is found.
"""
# pyd.get indexes by position, which needs a sequence. A mapping is left
# alone because it is indexed by key rather than position, and realizing
# one would look up its keys instead.
if not isinstance(array, (Sequence, Mapping)):
if isinstance(pos, int) and pos >= 0:
return next((value for index, value in enumerate(array) if index == pos), None)
array = list(array)
return pyd.get(array, pos)

Expand Down
15 changes: 15 additions & 0 deletions tests/test_arrays.py
Original file line number Diff line number Diff line change
Expand Up @@ -705,6 +705,21 @@ def test_nth_with_non_sequence_iterables(factory, pos, expected):
assert _.nth(factory(), pos) == expected


@parametrize("pos", [0, 2])
def test_nth_only_consumes_through_the_requested_position(pos):
def values():
yield from range(pos + 1)
pytest.fail("nth consumed an item after the requested position")

assert _.nth(values(), pos) == pos


def test_nth_leaves_remaining_items_in_the_iterator():
values = iter([11, 22, 33, 44])
assert _.nth(values, 1) == 22
assert list(values) == [33, 44]


@parametrize(
"case,pos,expected",
[({0: "x", 1: "y"}, 0, "x"), ({0: "x", 1: "y"}, 1, "y"), ({"a": 1}, 0, None)],
Expand Down