From ae9501164d312fec67a690e628f43c99ef0681f5 Mon Sep 17 00:00:00 2001 From: Samer Hamood Date: Sat, 4 Jan 2025 19:49:28 +0000 Subject: [PATCH 1/3] Add filter_not_none function that filters out None values --- functional/pipeline.py | 11 +++++++++++ functional/test/test_functional.py | 15 +++++++++++++++ functional/test/test_type.py | 2 ++ 3 files changed, 28 insertions(+) diff --git a/functional/pipeline.py b/functional/pipeline.py index a6ef89f..641cbec 100644 --- a/functional/pipeline.py +++ b/functional/pipeline.py @@ -803,6 +803,17 @@ def filter_not(self, func: Callable[[_T_co], Any]) -> Sequence[_T_co]: """ return self._transform(transformations.filter_not_t(func)) + def filter_not_none(self): + """ + Filters sequence to include only elements that are not None. + + >>> seq([1, None, 2, None, 3]).filter_not_none() + [1, 2, 3] + + :return: sequence with None filtered out + """ + return self.filter_not(lambda x: x is None) + def where(self, func: Callable[[_T_co], Any]) -> Sequence[_T_co]: """ Selects elements where func evaluates to True. diff --git a/functional/test/test_functional.py b/functional/test/test_functional.py index f35e7d2..70010d9 100644 --- a/functional/test/test_functional.py +++ b/functional/test/test_functional.py @@ -401,6 +401,21 @@ def test_filter_not(self): self.assertIteratorEqual(expect, result) self.assert_type(result) + @parametrize( + "sequence, expected", + [ + ([1, None, 2, None, 3, None, 4, None, 5], [1, 2, 3, 4, 5]), + ([None, None, 1, 2, 3, None, 4, 5, None], [1, 2, 3, 4, 5]), + ([1, 2, 3, 4, 5], [1, 2, 3, 4, 5]), + ([None, None, None, None, None], []), + ([], []), + ], + ) + def test_filter_not_none(self, sequence, expected): + result = self.seq(sequence).filter_not_none() + self.assertIteratorEqual(expected, result) + self.assert_type(result) + def test_map_filter(self): f = lambda x: x > 0 g = lambda x: x * 2 diff --git a/functional/test/test_type.py b/functional/test/test_type.py index c9d0644..8bc22c7 100644 --- a/functional/test/test_type.py +++ b/functional/test/test_type.py @@ -92,6 +92,8 @@ def type_checking() -> None: t_filter_not: Sequence[int] = seq([-1, 1, -2, 2]).filter_not(lambda x: x > 0) + t_filter_not_none: Sequence[int] = seq([-1, 1, None, 2]).filter_not_none() + t_where: Sequence[int] = seq([-1, 1, -2, 2]).where(lambda x: x > 0) t_count: int = seq([-1, -2, 1, 2]).count(lambda x: x > 0) From 9bab49b66db15ebd7e3fa030e8602615f9094d44 Mon Sep 17 00:00:00 2001 From: Samer Hamood Date: Sat, 4 Jan 2025 19:52:18 +0000 Subject: [PATCH 2/3] Add filter_not_none function to Transformations and Actions APIs table --- README.md | 1 + 1 file changed, 1 insertion(+) diff --git a/README.md b/README.md index f6c0e32..bd1794b 100644 --- a/README.md +++ b/README.md @@ -344,6 +344,7 @@ complete documentation reference | `starmap(func)/smap(func)` | Applies `func` to sequence with `itertools.starmap` | transformation | | `filter(func)/where(func)` | Filters elements of sequence to only those where `func(element)` is `True` | transformation | | `filter_not(func)` | Filters elements of sequence to only those where `func(element)` is `False` | transformation | +| `filter_not_none()` | Filters all None values from sequence | transformation | | `flatten()` | Flattens sequence of lists to a single sequence | transformation | | `flat_map(func)` | Maps `func` to each element, then merges the result to one flat sequence. `func` must return an iterable | transformation | | `group_by(func)` | Groups sequence into `(key, value)` pairs where `key=func(element)` and `value` is from the original sequence | transformation | From 9ada0df8097301f2f6d2cdd32e8eee4316a2fd33 Mon Sep 17 00:00:00 2001 From: Samer Hamood Date: Mon, 20 Jan 2025 21:29:28 +0000 Subject: [PATCH 3/3] Add filter_not_none function to CHANGELOG.md --- CHANGELOG.md | 1 + 1 file changed, 1 insertion(+) diff --git a/CHANGELOG.md b/CHANGELOG.md index c3fb0d4..9cb263b 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -12,6 +12,7 @@ ### New Features +- Implemented `filter_not_none` filter function that removes `None` from sequence - Added `first_or_none`, a function to match `head_or_none` - Added run_test.sh script - Added [parametrize](https://pypi.org/project/parametrize/) for parameterized unit tests