From f81103b1a7fcbfcaa2d2343565c905530281d197 Mon Sep 17 00:00:00 2001 From: Voltra Date: Mon, 25 Mar 2024 11:18:36 +0000 Subject: [PATCH 1/2] Add flatMapM implementation --- src/Sequence.ts | 5 +++-- src/flatMapM.ts | 23 +++++++++++++++++++++++ 2 files changed, 26 insertions(+), 2 deletions(-) create mode 100644 src/flatMapM.ts diff --git a/src/Sequence.ts b/src/Sequence.ts index 76eb3c3..a1e4389 100644 --- a/src/Sequence.ts +++ b/src/Sequence.ts @@ -21,6 +21,7 @@ import {FilterNotNull} from "./filterNotNull"; import {First} from "./first"; import {FirstOrNull} from "./firstOrNull"; import {FlatMap} from "./flatMap"; +import {FlatMapM} from "./flatMapM"; import {Flatten} from "./flatten"; import {Fold} from "./fold"; import {FoldIndexed} from "./foldIndexed"; @@ -87,7 +88,7 @@ export default Sequence; * @hidden */ export interface SequenceOperators extends All, Any, AsIterable, Associate, AssociateBy, Average, Chunk, Contains, Count, Distinct, DistinctBy, Drop, - DropWhile, ElementAt, ElementAtOrElse, ElementAtOrNull, Filter, FilterIndexed, FilterNot, FilterNotNull, First, FirstOrNull, FlatMap, Flatten, Fold, FoldIndexed, + DropWhile, ElementAt, ElementAtOrElse, ElementAtOrNull, Filter, FilterIndexed, FilterNot, FilterNotNull, First, FirstOrNull, FlatMap, FlatMapM, Flatten, Fold, FoldIndexed, ForEach, ForEachIndexed, GroupBy, IndexOf, IndexOfFirst, IndexOfLast, JoinToString, Last, LastOrNull, Map, MapIndexed, MapNotNull, Max, MaxBy, MaxWith, Merge, Min, MinBy, Minus, MinWith, None, OnEach, Partition, Plus, Reduce, ReduceIndexed, Reverse, Single, SingleOrNull, Sorted, SortedBy, SortedByDescending, SortedDescending, SortedWith, Sum, SumBy, Take, TakeWhile, ToArray, ToMap, ToSet, Unzip, WithIndex, Zip { @@ -99,7 +100,7 @@ class SequenceImpl { } applyMixins(SequenceImpl, [All, Any, AsIterable, Associate, AssociateBy, Average, Chunk, Contains, Count, Distinct, DistinctBy, Drop, - DropWhile, ElementAt, ElementAtOrElse, ElementAtOrNull, Filter, FilterIndexed, FilterNot, FilterNotNull, First, FirstOrNull, FlatMap, Flatten, Fold, FoldIndexed, + DropWhile, ElementAt, ElementAtOrElse, ElementAtOrNull, Filter, FilterIndexed, FilterNot, FilterNotNull, First, FirstOrNull, FlatMap, FlatMapM, Flatten, Fold, FoldIndexed, ForEach, ForEachIndexed, GroupBy, IndexOf, IndexOfFirst, IndexOfLast, JoinToString, Last, LastOrNull, Map, MapIndexed, MapNotNull, Max, MaxBy, MaxWith, Merge, Min, MinBy, Minus, MinWith, None, OnEach, Partition, Plus, Reduce, ReduceIndexed, Reverse, Single, SingleOrNull, Sorted, SortedBy, SortedByDescending, SortedDescending, SortedWith, Sum, SumBy, Take, TakeWhile, ToArray, ToMap, ToSet, Unzip, WithIndex, Zip]); diff --git a/src/flatMapM.ts b/src/flatMapM.ts new file mode 100644 index 0000000..ca61b1f --- /dev/null +++ b/src/flatMapM.ts @@ -0,0 +1,23 @@ +import Sequence, { asSequence } from "./Sequence"; + +export class FlatMapM { + /** + * Transforms each element into an iterable of items and returns a flat single sequence of all those items. The M stands for Monadic + * + * @param {(value: S) => Iterable} transform + * @returns {Sequence} + * @example + * asSequence(document.querySelectorAll("form")) + * .flatMapM(form => form.querySelectorAll("input")) + * // same as + * asSequence(document.querySelectorAll("form")) + * .map(form => form.querySelectorAll("input")) + * .flatMap(asSequence) + * + * + */ + flatMapM(this: Sequence, transform: (value: S) => Iterable): Sequence { + return this.flatMap(value => asSequence(transform(value))); + } + +} \ No newline at end of file From a48b5021f80d015583ad5f70ec95c7ea2ed77d35 Mon Sep 17 00:00:00 2001 From: Voltra Date: Mon, 25 Mar 2024 11:29:28 +0000 Subject: [PATCH 2/2] Add tests for flatMapM --- test/flatMapM.test.ts | 32 ++++++++++++++++++++++++++++++++ 1 file changed, 32 insertions(+) create mode 100644 test/flatMapM.test.ts diff --git a/test/flatMapM.test.ts b/test/flatMapM.test.ts new file mode 100644 index 0000000..e0be533 --- /dev/null +++ b/test/flatMapM.test.ts @@ -0,0 +1,32 @@ +import { asSequence, sequenceOf } from "../src/Sequence"; + +describe("flatMapM", () => { + it("should flatten element arrays", () => { + const array = sequenceOf([1, 2], [3, 4], [5, 6]) + .flatMapM(it => it) + .toArray(); + + expect(array.length).toBe(6); + expect(array[0]).toBe(1); + expect(array[1]).toBe(2); + expect(array[2]).toBe(3); + expect(array[3]).toBe(4); + expect(array[4]).toBe(5); + expect(array[5]).toBe(6); + }); + + it("should flatten iterable iterators", () => { + const array = asSequence([ + new Map([["a", 1], ["c", 3]]), + new Map([["b", 2], ["d", 4]]), + ]) + .flatMapM(map => map.values()) + .toArray(); + + expect(array.length).toBe(4); + expect(array[0]).toBe(1); + expect(array[1]).toBe(3); + expect(array[2]).toBe(2); + expect(array[3]).toBe(4); + }); +}); \ No newline at end of file