From ed9b7b410990923190316cf9200222261a65d32e Mon Sep 17 00:00:00 2001 From: AbdulFattah Popoola Date: Sun, 25 Oct 2015 18:03:52 -0700 Subject: [PATCH] Fixed bug in zip and added Natural numbers support --- api/documentation.md | 15 +++++++++++- spec/stream.js | 54 +++++++++++++++++++++++++++++++++++++++++++- stream.js | 51 +++++++++++++++++++++++++++++++++++++---- 3 files changed, 113 insertions(+), 7 deletions(-) diff --git a/api/documentation.md b/api/documentation.md index 36bf6a1..85da494 100644 --- a/api/documentation.md +++ b/api/documentation.md @@ -88,6 +88,9 @@
Ones()Stream

Returns an infinite stream of ones

+
NaturalNumbers()Stream
+

Returns the stream of Natural numbers

+
## Stream @@ -419,8 +422,18 @@ Constructs a stream made up of consecutive numbers up to `stop` Returns an infinite stream of ones **Kind**: global function -**Returns**: [Stream](#Stream) - Value at nth index in stream +**Returns**: [Stream](#Stream) - An infinite stream of Ones **Example** ```js var ones = Stream.Ones(); ``` + +## NaturalNumbers() ⇒ [Stream](#Stream) +Returns the stream of Natural numbers + +**Kind**: global function +**Returns**: [Stream](#Stream) - The infinite stream of natural numbers +**Example** +```js +var naturals = Stream.NaturalNumbers(); +``` diff --git a/spec/stream.js b/spec/stream.js index 85837c9..98482ad 100644 --- a/spec/stream.js +++ b/spec/stream.js @@ -133,6 +133,21 @@ describe('Stream()', function () { expect(sum.elementAt(4)).to.deep.equal([25]); }); + it('can append a new stream onto an existing stream', function () { + var s1 = Stream.fromArray([1,3,5]); + var s2 = Stream.fromArray([2,4,6]); + var concatenated = s1.append(s2); + expect(concatenated.length()).to.equal(6); + expect(concatenated.toArray()).to.deep.equal([1,3,5,2,4,6]); + }); + + it('can pick a new stream from an existing stream', function () { + var s1 = Stream.fromArray([1,3,5,7,9,11]); + var s2 = s1.pick(3); + expect(s2.length()).to.equal(3); + expect(s2.toArray()).to.deep.equal([1,3,5]); + }); + it('can find the length of a stream', function () { var s1 = Stream.fromArray([1,3,5]); var sum = s1.length(); @@ -178,6 +193,27 @@ describe('Stream()', function () { }); expect(triples.toArray()).to.deep.equal([3,9,15]); }); + + it('can filter streams', function () { + var s1 = Stream.fromArray([1,2,3,4,5]); + var evenNumbers = s1.filter(function (element) { + return element % 2 === 0; + }); + expect(evenNumbers.toArray()).to.deep.equal([2,4]); + }); + + it('can test for membership of a stream', function () { + var s1 = Stream.fromArray([1,2,3,4,5]); + expect(s1.contains(2)).to.equal(true); + expect(s1.contains(-2)).to.equal(false); + }); + + it('can remove elements from a stream', function () { + var s1 = Stream.fromArray([1,2,3,4,5]); + s1 = s1.remove(2); + expect(s1.length()).to.equal(3); + expect(s1.toArray()).to.deep.equal([3,4,5]); + }); it('can convert a finite stream to an array', function () { var s1 = Stream.fromArray([1,3,5]); @@ -185,5 +221,21 @@ describe('Stream()', function () { return 2 * element; }); expect(doubled.toArray()).to.deep.equal([2,6,10]); - }); + }); + + it('Ones return an infinite number of Ones', function () { + var s1 = Stream.Ones(); + + var first5Elements = s1.pick(5); + expect(first5Elements.toArray()).to.deep.equal([1,1,1,1,1]); + + expect(s1.elementAt(1000)).to.equal(1); + }); + + it('NaturalNumbers returns the infinite stream of Natural Numbers', function () { + var s1 = Stream.NaturalNumbers(); + + var first5Elements = s1.pick(5); + expect(first5Elements.toArray()).to.deep.equal([1,2,3,4,5]); + }); }); diff --git a/stream.js b/stream.js index a5d0890..c970581 100644 --- a/stream.js +++ b/stream.js @@ -121,7 +121,11 @@ function elementAt(index) { if(s.isEmpty()) { return; } - s = s.tail(); + try { + s = s.tail(); + } catch (e){ + return; + } index--; } @@ -325,6 +329,7 @@ function remove(n) { return new Stream(null, null); } s = s.tail(); + n--; } return new Stream( @@ -395,13 +400,28 @@ function zip(/* arguments */) { continue; } zippedFirsts.push(s.head()); - args[i] = s.tail(); //overwrite stream with tail } + //Find cleaner pattern return new Stream( zippedFirsts, function () { - return Stream.zip.apply(null, args); + var moved = []; + for(var i=0, len = args.length; i < len; i++){ + var tmp = args[i]; + var hasTail = true; + try { + tmp = tmp.tail(); + } catch (e) { + hasTail = false; + } finally { + if(hasTail) { + moved.push(tmp); + } + } + } + + return Stream.zip.apply(null, moved); } ); } @@ -508,7 +528,7 @@ function upTo(stop){ * Returns an infinite stream of ones * * @static -* @returns {Stream} Value at nth index in stream +* @returns {Stream} An infinite stream of Ones * @example * * var ones = Stream.Ones(); @@ -517,6 +537,26 @@ function Ones() { return new Stream(1, Ones); }; +/** +* Returns the stream of Natural numbers +* +* @static +* @returns {Stream} The infinite stream of natural numbers +* @example +* +* var naturals = Stream.NaturalNumbers(); +**/ +function NaturalNumbers() { + return new Stream( + 1, + function () { + return Stream.add( + Stream.NaturalNumbers(), + Stream.Ones()); + } + ); +}; + //Instance methods Stream.prototype.head = head; Stream.prototype.tail = tail; @@ -543,4 +583,5 @@ Stream.fromArray = fromArray; Stream.fromInterval = fromInterval; Stream.from = from; Stream.upTo = upTo; -Stream.Ones = Ones; \ No newline at end of file +Stream.Ones = Ones; +Stream.NaturalNumbers = NaturalNumbers; \ No newline at end of file