Skip to content

Instantly share code, notes, and snippets.

@tmatz
Last active March 19, 2019 05:21
Show Gist options
  • Save tmatz/83578bec4171eb60da5abefef43e8265 to your computer and use it in GitHub Desktop.
Save tmatz/83578bec4171eb60da5abefef43e8265 to your computer and use it in GitHub Desktop.
JavaScript LINQ-like collection evaluation
test('try implement LINQ.', () => {
class Enumerable {
static from(array) {
return new Enumerable(
function*() {
yield* array;
})
}
constructor(generator) {
this.generator = generator;
}
[Symbol.iterator]() {
return this.generator();
}
toArray() {
return Array.from(this)
}
filter(func) {
const source = this;
function* generator() {
let i = 0;
for (const x of source) {
if (func(x, i++)) {
yield x;
}
}
}
return new Enumerable(generator);
}
take(num) {
const source = this;
function* generator() {
// should not iterate not requested items.
if (num <= 0) {
return;
}
let i = 0;
for (const x of source) {
yield x;
if (++i == num)
{
return;
}
}
}
return new Enumerable(generator);
}
skip(num) {
return this.filter((x, i) => i >= num);
}
map(func) {
const source = this;
function* generator() {
let i = 0;
for (const x of source) {
yield func(x, i++);
}
}
return new Enumerable(generator);
}
do(func) {
return this.map((x, i) => {
func(x, i);
return x;
})
}
reduce(func, acc) {
let i = 0
for (const x of this) {
acc = func(acc, x, i++);
}
return acc;
}
}
Array.prototype.asEnumerable = function asEnumerable() {
return Enumerable.from(this);
}
const output = [];
const odd = x => x % 2 == 1;
const square = x => x * x;
const log = msg => x => {
output.push(msg + x);
}
const array = [0,1,2,3];
output.push(array);
output.push(array
.asEnumerable()
.filter(odd)
.map(square)
.toArray());
output.push(array
.asEnumerable()
.take(3)
.toArray());
output.push(array
.asEnumerable()
.skip(3)
.toArray());
// deferred evaluation
output.push(array
.asEnumerable()
.do(log('a '))
.filter(odd)
.do(log('b '))
.map(square)
.do(log('c '))
.toArray());
return output
.map(JSON.stringify)
.join("\n");
})
=> [0,1,2,3]
[1,9]
[0,1,2]
[3]
"a 0"
"a 1"
"b 1"
"c 1"
"a 2"
"a 3"
"b 3"
"c 9"
[1,9]
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment