Skip to content

Commit c9fb734

Browse files
committed
rename to stream and add bind method and empty stream
1 parent 7ebdab3 commit c9fb734

File tree

4 files changed

+88
-21
lines changed

4 files changed

+88
-21
lines changed

README.md

Lines changed: 3 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -1,10 +1,10 @@
1-
# list8
2-
a js data structure for infinity lazy list and some method to control the list. 8 indicates infinity
1+
# Stream
2+
a js data structure for stream processing.
33

44
## Usage
55

66
```javascript
7-
const {cons} = require('list8');
7+
const {cons} = require('.');
88

99
// you can put tail in () => ... to reference self
1010
const N = cons(1, () => N.map(n => n + 1));

index.js

Lines changed: 63 additions & 12 deletions
Original file line numberDiff line numberDiff line change
@@ -1,4 +1,4 @@
1-
module.exports = class LazyList {
1+
module.exports = class Stream {
22
constructor(fn) {
33
this.visited = false;
44
this.fn = fn;
@@ -16,26 +16,39 @@ module.exports = class LazyList {
1616
get tail() {
1717
return this.value[1];
1818
}
19+
get isEmpty() {
20+
return this.value === Stream.EmptySymbol;
21+
}
22+
23+
static EmptySymbol = Symbol('Empty');
24+
25+
static Empty = new Stream(() => Stream.EmptySymbol);
1926

2027
static cons(head, tail) {
21-
if(tail instanceof LazyList)
22-
return new LazyList(() => [head, tail]);
28+
if(tail instanceof Stream)
29+
return new Stream(() => [head, tail]);
2330
else
24-
return new LazyList(() => [head, tail()]);
31+
return new Stream(() => [head, tail()]);
2532
}
2633

27-
drop(num) {
28-
return new LazyList(() => {
29-
return num === 0 ? this.value : this.tail.drop(num - 1).value;
30-
});
34+
static list(x, ...xs) {
35+
if(x === undefined)
36+
return Stream.Empty;
37+
return Stream.cons(x, Stream.list(...xs));
3138
}
3239

3340
map(fn) {
34-
return new LazyList(() => [fn(this.head), this.tail.map(fn)]);
41+
return new Stream(() => {
42+
if(this.isEmpty)
43+
return this.value;
44+
return [fn(this.head), this.tail.map(fn)];
45+
});
3546
}
3647

3748
filter(fn) {
38-
return new LazyList(() => {
49+
return new Stream(() => {
50+
if(this.isEmpty)
51+
return this.value;
3952
if(fn(this.head))
4053
return [this.head, this.tail.filter(fn)];
4154
else
@@ -44,13 +57,51 @@ module.exports = class LazyList {
4457
}
4558

4659
zipWith(otherList, fn) {
47-
return new LazyList(() => {
60+
return new Stream(() => {
61+
if(this.isEmpty || otherList.isEmpty)
62+
return Stream.Empty.value;
4863
return [fn(this.head, otherList.head), this.tail.zipWith(otherList.tail, fn)];
4964
});
5065
}
5166

67+
concat(otherList) {
68+
return new Stream(() => {
69+
if(this.isEmpty)
70+
return otherList.value;
71+
return [this.head, this.tail.concat(otherList)];
72+
});
73+
}
74+
75+
flatten() {
76+
return new Stream(() => {
77+
if(this.isEmpty)
78+
return this.value;
79+
return this.head.concat(this.tail.flatten()).value;
80+
});
81+
}
82+
83+
bind(fn) {
84+
return this.map(fn).flatten();
85+
}
86+
87+
drop(num) {
88+
return new Stream(() => {
89+
if(this.isEmpty && num !== 0)
90+
throw new Error('No more element to drop');
91+
return num === 0 ? this.value: this.tail.drop(num - 1).value
92+
});
93+
}
94+
5295
take(num) {
5396
if(num === 0) return [];
54-
else return [this.head].concat(this.tail.take(num - 1));
97+
if(this.isEmpty)
98+
throw new Error('No more element to take');
99+
return [this.head].concat(this.tail.take(num - 1));
100+
}
101+
102+
takeAll() {
103+
if(this.isEmpty)
104+
return [];
105+
return [this.head].concat(this.tail.takeAll());
55106
}
56107
}

package.json

Lines changed: 5 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -1,14 +1,14 @@
11
{
2-
"name": "list8",
2+
"name": "stream",
33
"version": "0.0.2",
4-
"description": "a js structure for infinite lazy list and some method to control the list Edit",
4+
"description": "a js data structure for stream processing.",
55
"main": "index.js",
66
"scripts": {
77
"test": "node test.js"
88
},
99
"repository": {
1010
"type": "git",
11-
"url": "git+https://github.com/waksana/infinite-list.git"
11+
"url": "git+https://github.com/waksana/stream.git"
1212
},
1313
"keywords": [
1414
"list",
@@ -17,7 +17,7 @@
1717
"author": "[email protected]",
1818
"license": "MIT",
1919
"bugs": {
20-
"url": "https://github.com/waksana/infinite-list/issues"
20+
"url": "https://github.com/waksana/stream/issues"
2121
},
22-
"homepage": "https://github.com/waksana/infinite-list#readme"
22+
"homepage": "https://github.com/waksana/stream#readme"
2323
}

test.js

Lines changed: 17 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,9 @@
1-
var {cons} = require('.');
1+
var {cons, list, Empty} = require('.');
22
var assert = require('assert');
33

4+
cons(n => [1, n.map()]);
5+
(ones) => cons(1, ones);
6+
47
var N = cons(1, () => N.map(n => n + 1)); //nature number list
58
var ones = cons(1, () => ones);
69

@@ -22,3 +25,16 @@ assert.deepEqual(prime.take(5), [2, 3, 5, 7, 11]);
2225
var fibs = cons(0, cons(1, () => fibs.zipWith(fibs.tail, (a, b) => a + b)));
2326

2427
assert.deepEqual(fibs.take(6), [0, 1, 1, 2, 3, 5]);
28+
29+
//flatten
30+
assert.deepEqual(ones.map(o => list(1,2,3)).flatten().take(5), [1, 2, 3, 1, 2]);
31+
32+
//bind
33+
assert.deepEqual(list(1, 2, 3).bind(x => list(9, 8, 7).bind(y => x + y > 9 ? list({x, y}) : Empty)).takeAll(), [
34+
{ x: 1, y: 9 },
35+
{ x: 2, y: 9 },
36+
{ x: 2, y: 8 },
37+
{ x: 3, y: 9 },
38+
{ x: 3, y: 8 },
39+
{ x: 3, y: 7 }
40+
]);

0 commit comments

Comments
 (0)