-
Notifications
You must be signed in to change notification settings - Fork 1
/
Copy pathlist-ops.js
115 lines (92 loc) · 2.12 KB
/
list-ops.js
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
class ValuesBuffer {
constructor() {
this._buffer = [];
this._bufferIndex = 0;
}
get buffer() {
return this._buffer;
}
get bufferIndex() {
return this._bufferIndex;
}
add(value) {
this._buffer[this._bufferIndex] = value;
this._bufferIndex++;
return this;
}
toList() {
return new List(this._buffer);
}
}
export class List {
constructor(values) {
this._values = values ? values : [];
}
get values() {
return this._values;
}
length() {
return this._values.length;
}
forEach(valueOperator) {
for (let index = 0; index < this._values.length; index++) {
const value = this._values[index];
valueOperator(value, index);
}
}
reverseForEach(valueOperator) {
for (let index = this._values.length - 1; index >= 0; index--) {
const value = this._values[index];
valueOperator(value, index);
}
}
foldl(valueReduceOperator, initial) {
let acc = initial;
this.forEach(value => {
acc = valueReduceOperator(acc, value);
});
return acc;
}
foldr(valueReduceOperator, initial) {
let acc = initial;
this.reverseForEach(value => {
acc = valueReduceOperator(acc, value);
});
return acc;
}
append(list) {
return list
.foldl(
(buffer, listValue) => buffer.add(listValue),
this.foldl((buffer, value) => buffer.add(value), new ValuesBuffer())
)
.toList();
}
concat(lists) {
return lists
.foldl(
(buffer, list) =>
list.foldl((buffer, listValue) => buffer.add(listValue), buffer),
this.foldl((buffer, value) => buffer.add(value), new ValuesBuffer())
)
.toList();
}
filter(predicate) {
return this.foldl(
(buffer, value) => (predicate(value) ? buffer.add(value) : buffer),
new ValuesBuffer()
).toList();
}
map(valueOperator) {
return this.foldl(
(buffer, value) => buffer.add(valueOperator(value)),
new ValuesBuffer()
).toList();
}
reverse() {
return this.foldr(
(buffer, value) => buffer.add(value),
new ValuesBuffer()
).toList();
}
}