From 6568e836eb47ede406b40e32e29dd148240904f1 Mon Sep 17 00:00:00 2001 From: Gaetano Checinski Date: Sun, 14 Jun 2015 12:14:18 +0200 Subject: [PATCH] Implemented iterable/zip. --- src/iterable/zip.js | 36 +++++++++++++++++++++++++++++++++ test/spec/iterable/zipSpec.js | 38 +++++++++++++++++++++++++++++++++++ 2 files changed, 74 insertions(+) create mode 100644 src/iterable/zip.js create mode 100644 test/spec/iterable/zipSpec.js diff --git a/src/iterable/zip.js b/src/iterable/zip.js new file mode 100644 index 0000000..9f6623f --- /dev/null +++ b/src/iterable/zip.js @@ -0,0 +1,36 @@ +/** + * Yields groups of elements where the first group contains the first elements + * of all the iterators, second contains the second items and etc. until one + * of the iterators has been exhausted. + * + * @this {Iterable>} + * @ntime O(nm) + * @dspace O(m) + * @example Basic Usage + * + * ```javascript + * [ [1,2], [4,5], [6,7] ]::zip() // yields [1,4,6], [2,5,7] + * ``` +*/ + +export function * zip () : Iterable> { + const iterators = [...this].map( + (iterable) => iterable[Symbol.iterator]() + ); + + if ( iterators.length === 0 ) { return; } + + while ( true ) { + const zipped = []; + + for ( const iterator of iterators ) { + const { value, done } = iterator.next(); + + if ( done ) { return; } + + zipped.push(value); + } + + yield zipped; + } +}; diff --git a/test/spec/iterable/zipSpec.js b/test/spec/iterable/zipSpec.js new file mode 100644 index 0000000..b7ec7aa --- /dev/null +++ b/test/spec/iterable/zipSpec.js @@ -0,0 +1,38 @@ +import { zip } from "../../../src/iterable/zip"; + +function * iter () { + let i = 0; + + while ( true ) { + yield ++i; + } +} + +function * iterIter () { + yield iter(); + yield [4, 5]; + yield [6, 7]; +} + +describe("zip()", function () { + const zipped = [ + [1, 4, 6], + [2, 5, 7], + ]; + + it("should zip empty arrays", function () { + const toZip = [[1, 2, 3],[]]; + [...toZip::zip()].should.deep.equal([]); + [...[]::zip()].should.deep.equal([]); + }); + + it("should zip arrays correctly", function () { + const toZip = [ [1, 2, 3], [4, 5], [6, 7] ]; + [...toZip::zip()].should.deep.equal(zipped); + }); + + it("should zip iterators correctly", function () { + const toZip = iterIter(); + [...toZip::zip()].should.deep.equal(zipped); + }); +});