diff --git a/src/iterable/flattenDeep.js b/src/iterable/flattenDeep.js new file mode 100644 index 0000000..162fa14 --- /dev/null +++ b/src/iterable/flattenDeep.js @@ -0,0 +1,27 @@ +"use strict"; + +/** + * Yields the elements in the iterable at the given depth. + * Flattening with depth of 1 is the same as doing a plain `flatten()`. + * + * @this {Iterable} + * @param depth The depth that the generator will flatten to. + * @example Basic Usage + * + * ```javascript + * [[[1],[2]]]::flattenDeep(2) // yields [1,2] + * ``` +*/ + +export function * flattenDeep ( + depth : number, +) : Iterable { + if ( depth < 0 ) { + yield this; + return; + } + + for ( const item of this ) { + yield * item::flattenDeep(depth - 1); + } +}; diff --git a/test/spec/iterable/flattenDeepSpec.js b/test/spec/iterable/flattenDeepSpec.js new file mode 100644 index 0000000..8cf419b --- /dev/null +++ b/test/spec/iterable/flattenDeepSpec.js @@ -0,0 +1,34 @@ +"use strict"; + +import { flattenDeep } from "../../../src/iterable/flattenDeep"; + +describe("flattenDeep()", function () { + + it("should throw when trying to flatten a non iterable item", function () { + void function () { + [...[1,2,3]::flattenDeep(1)] + }.should.throw(); + }) + + it("should flatten a simple nested array", function () { + [...[[1],[2]]::flattenDeep(1)].should.deep.equal([1,2]); + }); + + it("should flattenDeep to 1 level deep", function () { + [...[[[[1]],[2,[3]]]]::flattenDeep(1)].should.deep.equal([[[1]],[2,[3]]]); + }); + + it("should flattenDeep to 2 levels deep", function () { + [...[[[[1]],[2,[3]]]]::flattenDeep(2)].should.deep.equal([[1],2,[3]]); + }); + + it("should flattenDeep to 3 levels deep", function () { + [...[[[[1]],[[2],[3]]]]::flattenDeep(3)].should.deep.equal([1,2,3]); + }); + + it("should flattenDeep set with nested array", function () { + const set = new Set(["a", [1,2,3]]); + [...[set]::flattenDeep(2)].should.deep.equal(["a",1,2,3]); + }); + +});