Skip to content

Commit

Permalink
Feature: to_dict(key, duplicated=reducer)
Browse files Browse the repository at this point in the history
Allow to pass reducer to to_dict.
This makes it possible to select items according to specific conditions when keys are duplicated.
For example, it will be possible to take out the largest item and take out the smallest item.
  • Loading branch information
kitsuyui committed Aug 26, 2022
1 parent 287a68f commit 1c887d1
Show file tree
Hide file tree
Showing 2 changed files with 18 additions and 5 deletions.
5 changes: 3 additions & 2 deletions richset/__init__.py
Original file line number Diff line number Diff line change
Expand Up @@ -18,6 +18,7 @@
T = TypeVar("T")
S = TypeVar("S")
Key = TypeVar("Key", bound=Hashable)
OnDuplicateActions = Literal["error", "first", "last"]


@dataclass(frozen=True)
Expand Down Expand Up @@ -93,7 +94,7 @@ def to_dict(
self,
key: Callable[[T], Key],
*,
duplicated: Literal["error", "first", "last"] = "error",
duplicated: OnDuplicateActions | Callable[[list[T]], T] = "error",
) -> dict[Key, T]:
"""Returns a dictionary mapping keys to values.
Expand All @@ -112,7 +113,7 @@ def to_dict(
elif duplicated == "last":
return {k: v[-1] for k, v in base.items()}
else:
raise ValueError("invalid duplicated value")
return {k: duplicated(v) for k, v in base.items()}

def to_dict_of_list(
self,
Expand Down
18 changes: 15 additions & 3 deletions tests/test_conversions.py
Original file line number Diff line number Diff line change
Expand Up @@ -167,9 +167,21 @@ def test_richset_to_dict() -> None:
"jane": Something(2, "jane"),
}

with pytest.raises(ValueError) as err:
rs.to_dict(lambda r: r.name, duplicated="invalid") # type: ignore
assert str(err.value) == "invalid duplicated value"
# test with a custom duplicate key function
assert rs.to_dict(
lambda r: r.name,
duplicated=lambda items: min(items, key=lambda item: item.id),
) == {
"john": Something(1, "john"),
"jane": Something(2, "jane"),
}
assert rs.to_dict(
lambda r: r.name,
duplicated=lambda items: max(items, key=lambda item: item.id),
) == {
"john": Something(3, "john"),
"jane": Something(2, "jane"),
}


def test_richset_to_dict_of_list() -> None:
Expand Down

0 comments on commit 1c887d1

Please sign in to comment.