Skip to content

Commit e8c6abb

Browse files
committed
✨ Stream機能追加
1 parent 0c53121 commit e8c6abb

13 files changed

+1279
-9
lines changed

dist/JavaLibraryScript.js

Lines changed: 637 additions & 2 deletions
Some generated files are not rendered by default. Learn more about customizing how changed files appear on GitHub.

dist/JavaLibraryScript.js.map

Lines changed: 18 additions & 4 deletions
Some generated files are not rendered by default. Learn more about customizing how changed files appear on GitHub.

dist/JavaLibraryScript.min.js

Lines changed: 1 addition & 1 deletion
Some generated files are not rendered by default. Learn more about customizing how changed files appear on GitHub.

dist/JavaLibraryScript.min.js.map

Lines changed: 1 addition & 1 deletion
Some generated files are not rendered by default. Learn more about customizing how changed files appear on GitHub.

src/libs/TypeChecker.js

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -115,6 +115,7 @@ class TypeChecker extends JavaLibraryScriptCore {
115115
static checkClass(fn) {
116116
if (typeof fn !== "function") return false;
117117
if (this._CLASS_REG.test(fn.toString())) return true;
118+
if (fn === Function) return true;
118119
try {
119120
new new Proxy(fn, { construct: () => ({}) })();
120121
return true;

src/util/index.js

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -2,5 +2,6 @@ module.exports = {
22
BaseMap: require("./BaseMap.js"),
33
HashMap: require("./HashMap.js"),
44
LinkedHashMap: require("./LinkedHashMap.js"),
5-
TreeMap: require("./TreeMap.js")
5+
TreeMap: require("./TreeMap.js"),
6+
stream: require("./stream")
67
};

src/util/stream/AsyncStream.js

Lines changed: 172 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,172 @@
1+
const StreamInterface = require("./StreamInterface.js");
2+
const Stream = require("./Stream.js");
3+
4+
class AsyncStream extends StreamInterface {
5+
constructor(source) {
6+
super();
7+
this._iter = AsyncStream._normalize(source);
8+
this._pipeline = [];
9+
}
10+
11+
static from(iterable) {
12+
return new AsyncStream(iterable);
13+
}
14+
15+
static _normalize(input) {
16+
if (typeof input[Symbol.asyncIterator] === "function") return input;
17+
if (typeof input[Symbol.iterator] === "function") {
18+
return (async function* () {
19+
for (const x of input) yield x;
20+
})();
21+
}
22+
throw new TypeError("not (Async)Iterable");
23+
}
24+
25+
_use(fn) {
26+
this._pipeline.push(fn);
27+
return this;
28+
}
29+
30+
// ==================================================
31+
// パイプライン計算
32+
// ==================================================
33+
34+
flattenPipeline() {
35+
const flattenedFn = this._pipeline.reduceRight(
36+
(nextFn, currentFn) => {
37+
return async function* (iterable) {
38+
yield* currentFn(nextFn(iterable));
39+
};
40+
},
41+
async function* (x) {
42+
yield* x;
43+
}
44+
);
45+
const flat = new this.constructor([]);
46+
flat._iter = this._iter;
47+
flat._pipeline = [flattenedFn];
48+
return flat;
49+
}
50+
51+
toFunction() {
52+
const flat = this.flattenPipeline();
53+
const fn = flat._pipeline[0];
54+
return (input) => fn(input);
55+
}
56+
57+
// ==================================================
58+
// Pipeline
59+
// ==================================================
60+
61+
map(fn) {
62+
return this._use(async function* (iter) {
63+
for await (const x of iter) yield await fn(x);
64+
});
65+
}
66+
67+
filter(fn) {
68+
return this._use(async function* (iter) {
69+
for await (const x of iter) {
70+
if (await fn(x)) yield x;
71+
}
72+
});
73+
}
74+
75+
flatMap(fn) {
76+
return this._use(async function* (iter) {
77+
for await (const x of iter) {
78+
const sub = await fn(x);
79+
for await (const y of AsyncStream._normalize(sub)) yield y;
80+
}
81+
});
82+
}
83+
84+
distinct(keyFn = (x) => x) {
85+
return this._use(async function* (iter) {
86+
const seen = new Set();
87+
for await (const x of iter) {
88+
const key = await keyFn(x);
89+
if (!seen.has(key)) {
90+
seen.add(key);
91+
yield x;
92+
}
93+
}
94+
});
95+
}
96+
97+
limit(n) {
98+
return this._use(async function* (iter) {
99+
let i = 0;
100+
for await (const x of iter) {
101+
if (i++ < n) yield x;
102+
else break;
103+
}
104+
});
105+
}
106+
107+
skip(n) {
108+
return this._use(async function* (iter) {
109+
let i = 0;
110+
for await (const x of iter) {
111+
if (i++ >= n) yield x;
112+
}
113+
});
114+
}
115+
116+
// ==================================================
117+
// Iterator
118+
// ==================================================
119+
120+
[Symbol.asyncIterator]() {
121+
let iter = this._iter;
122+
for (const op of this._pipeline) {
123+
iter = op(iter);
124+
}
125+
return iter[Symbol.asyncIterator]();
126+
}
127+
// ==================================================
128+
// End
129+
// ==================================================
130+
131+
async forEach(fn) {
132+
for await (const x of this) {
133+
await fn(x);
134+
}
135+
}
136+
137+
async toArray() {
138+
const result = [];
139+
for await (const x of this) {
140+
result.push(x);
141+
}
142+
return result;
143+
}
144+
145+
async reduce(fn, init) {
146+
let acc = init;
147+
for await (const x of this) {
148+
acc = await fn(acc, x);
149+
}
150+
return acc;
151+
}
152+
153+
count() {
154+
return this.reduce((acc) => acc + 1, 0);
155+
}
156+
157+
// ==================================================
158+
// mapTo
159+
// ==================================================
160+
161+
toLazy() {
162+
return new Promise(async (resolve) => {
163+
const arr = [];
164+
for await (const item of this) {
165+
arr.push(item);
166+
}
167+
resolve(new Stream(arr));
168+
});
169+
}
170+
}
171+
172+
module.exports = AsyncStream;

src/util/stream/EntryStream.js

Lines changed: 27 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,27 @@
1+
const Stream = require("./Stream.js");
2+
3+
class EntryStream extends Stream {
4+
constructor(source) {
5+
super(source);
6+
7+
this.mapToEntry = undefined;
8+
}
9+
10+
keys() {
11+
return this._convertToX(Stream).map(([k, _]) => k);
12+
}
13+
14+
values() {
15+
return this._convertToX(Stream).map(([_, v]) => v);
16+
}
17+
18+
mapKeys(fn) {
19+
return this.map(([k, v]) => [fn(k), v]);
20+
}
21+
22+
mapValues(fn) {
23+
return this.map(([k, v]) => [k, fn(v)]);
24+
}
25+
}
26+
27+
module.exports = EntryStream;

src/util/stream/NumberStream.js

Lines changed: 45 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,45 @@
1+
const Stream = require("./Stream.js");
2+
3+
class NumberStream extends Stream {
4+
constructor(source) {
5+
super(source);
6+
7+
this.mapToNumber = undefined;
8+
}
9+
10+
sum() {
11+
let total = 0;
12+
for (const num of this) {
13+
total += num;
14+
}
15+
return total;
16+
}
17+
18+
average() {
19+
let total = 0;
20+
let count = 0;
21+
for (const num of this) {
22+
total += num;
23+
count++;
24+
}
25+
return count === 0 ? NaN : total / count;
26+
}
27+
28+
min() {
29+
let min = Infinity;
30+
for (const num of this) {
31+
if (num < min) min = num;
32+
}
33+
return min === Infinity ? undefined : min;
34+
}
35+
36+
max() {
37+
let max = -Infinity;
38+
for (const num of this) {
39+
if (num > max) max = num;
40+
}
41+
return max === -Infinity ? undefined : max;
42+
}
43+
}
44+
45+
module.exports = NumberStream;

0 commit comments

Comments
 (0)