From 43d56786977ab929af485f1c947ad6ee1aca8ed3 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Micha=C3=ABl=20Lemaire?= Date: Thu, 26 Aug 2021 23:36:25 +0200 Subject: [PATCH] Add imapfilter function --- README.md | 1 + doc/use.md | 1 + mod.test.ts | 13 ++++++++++++- mod.ts | 20 ++++++++++++++++++++ 4 files changed, 34 insertions(+), 1 deletion(-) diff --git a/README.md b/README.md index b81898e..21334c0 100644 --- a/README.md +++ b/README.md @@ -64,6 +64,7 @@ iloop(i1); // 1 2 3 1 2 3 ... iskip(i3, 2); // -2 -3 -4 -5 -6 ... imap(i1, (x) => x * 2); // 2 4 6 ifilter(i3, (x) => x % 4 == 0); // 0 -4 -8 -12 ... +imapfilter(i1, (x) => x != 4 ? x * 2 : null); // 2 6 ipartition(i3, (x) => x % 4 == 0); // [0 -4 -8 ..., -1 -2 -3 -5 ...] iunique(iarray([1, 4, 2, 4, 3, 1, 5])); // 1 4 2 3 5 diff --git a/doc/use.md b/doc/use.md index 757a9b6..616e6b3 100644 --- a/doc/use.md +++ b/doc/use.md @@ -30,6 +30,7 @@ iloop(i1); // 1 2 3 1 2 3 ... iskip(i3, 2); // -2 -3 -4 -5 -6 ... imap(i1, (x) => x * 2); // 2 4 6 ifilter(i3, (x) => x % 4 == 0); // 0 -4 -8 -12 ... +imapfilter(i1, (x) => x != 4 ? x * 2 : null); // 2 6 ipartition(i3, (x) => x % 4 == 0); // [0 -4 -8 ..., -1 -2 -3 -5 ...] iunique(iarray([1, 4, 2, 4, 3, 1, 5])); // 1 4 2 3 5 diff --git a/mod.test.ts b/mod.test.ts index dcd0903..f1facf5 100644 --- a/mod.test.ts +++ b/mod.test.ts @@ -17,6 +17,7 @@ import { ilength, iloop, imap, + imapfilter, imaterialize, imax, imin, @@ -241,10 +242,20 @@ describe("Iterators", () => { }); it("filters an iterator with a predicate", () => { - checkit(imap(IEMPTY, (i) => i % 3 == 0), []); + checkit(ifilter(IEMPTY, (i) => i % 3 == 0), []); checkit(ifilter(irange(12), (i) => i % 3 == 0), [0, 3, 6, 9]); }); + it("maps and filters in a single pass", () => { + checkit(imapfilter(IEMPTY, (i) => i % 2 == 0 ? -i : null), []); + checkit(imapfilter(irange(8), (i) => i % 2 == 0 ? -i : null), [ + -0, + -2, + -4, + -6, + ]); + }); + it("filters an iterator with a type guard", () => { let result: Iterable = ifiltertype( <(number | string)[]> [1, "a", 2, "b"], diff --git a/mod.ts b/mod.ts index cfc5494..18faa9f 100644 --- a/mod.ts +++ b/mod.ts @@ -338,6 +338,26 @@ export function ifilter( }; } +/** + * Apply map, and filter invalid results in the same pass. + */ +export function imapfilter( + iterable: Iterable, + mapfunc: (_: T1) => Exclude | typeof exclusion, + exclusion: E = null as unknown as E, +): Iterable { + return { + [Symbol.iterator]: function* () { + for (let value of iterable) { + const mapped = mapfunc(value); + if (mapped !== exclusion) { + yield mapped as T2; + } + } + }, + }; +} + /** * Type filter, to return a list of instances of a given type */