Skip to content

Instantly share code, notes, and snippets.

@suspectpart
Last active February 6, 2019 23:29
Show Gist options
  • Save suspectpart/6f964b340a06ae4ed751cbf23d43eaf6 to your computer and use it in GitHub Desktop.
Save suspectpart/6f964b340a06ae4ed751cbf23d43eaf6 to your computer and use it in GitHub Desktop.
ES6 Generators
class Stream {
constructor(iterable, chain) {
this._iterable = iterable;
this._chain = chain || "";
}
static from(iterable) {
return new Stream(iterable);
}
map(function_) {
function* map_(iterable) {
for (let item of iterable) {
yield function_(item);
}
}
return new Stream(map_(this._iterable), this._chain + " > map")
}
filter(predicate) {
function* filter_(iterable) {
for (let item of iterable) {
if (predicate(item)) {
yield item;
}
}
}
return new Stream(filter_(this._iterable), this._chain + " > filter");
}
some(predicate) {
for (let item of this._iterable) {
if (predicate(item)) {
return true;
}
}
return false;
}
every(predicate) {
for (let item of this._iterable) {
if (!predicate(item)) {
return false;
}
}
return true;
}
take(number) {
function* take_(iterable) {
for (let item of iterable) {
if (number-- > 0) {
yield item;
} else {
break;
}
}
}
return new Stream(take_(this._iterable), this._chain + " > take");
}
toArray() {
return Array.from(this._iterable);
}
* [Symbol.iterator]() {
for (let item of this._iterable) {
yield item;
}
}
}
module.exports = Stream;
function* cycle(iterable) {
while (true) {
yield iterable[0];
iterable.push(iterable.shift());
}
}
Stream
.from(cycle(["a", "b", "c"]))
.map(chr => chr.toUpperCase())
.take(10)
.toArray()
.forEach((item, index) => console.log(`[${index}]: ${item}`))
const Stream = require('./istream');
const assert = require('assert');
describe("Stream", () => {
it("maps items", () => {
// Arrange
const items = [1, 2, 3, 4, 5, 6, 7, 8, 9, 10];
const expected = [1, 4, 9, 16, 25, 36, 49, 64, 81, 100];
// System under Test
const stream = new Stream(items);
// Act
const mapped = stream.map(i => i ** 2);
// Assert
assert.deepEqual(Array.from(mapped), expected);
});
it("filters items", () => {
// Arrange
const items = [1, 2, 3, 4, 5, 6, 7, 8, 9, 10];
const expected = [6, 7, 8, 9, 10];
// System under Test
const stream = new Stream(items);
// Act
const filtered = stream.filter(i => i > 5);
// Assert
assert.deepEqual(Array.from(filtered), expected);
});
it("succeeds matching some", () => {
// Arrange
const items = [1, 2, 3, 4, 5, 6, 7, 8, 9, 10];
// System under Test
const stream = new Stream(items);
// Act
const hasSome = stream.some(i => i > 5);
// Assert
assert(hasSome);
});
it("fails matching some", () => {
// Arrange
const items = [1, 2, 3, 4, 5, 6, 7, 8, 9, 10];
// System under Test
const stream = new Stream(items);
// Act
const hasSome = stream.some(i => i > 10);
// Assert
assert(!hasSome);
});
it("succeeds matching every", () => {
// Arrange
const items = [1, 2, 3, 4, 5, 6, 7, 8, 9, 10];
// System under Test
const stream = new Stream(items);
// Act
const every = stream.every(i => i < 11);
// Assert
assert(every);
});
it("converts to Array", () => {
// Arrange
const items = [1, 2, 3, 4, 5, 6, 7, 8, 9, 10];
// System under Test
const stream = new Stream(items);
// Act
const array = stream.toArray();
// Assert
assert.deepEqual(items, array);
});
it("fails matching every", () => {
// Arrange
const items = [1, 2, 3, 4, 5, 6, 7, 8, 9, 10];
// System under Test
const stream = new Stream(items);
// Act
const every = stream.every(i => i < 10);
// Assert
assert(!every);
});
it("chains calls", () => {
const items = [1, 2, 3, 4, 5, 6, 7, 8, 9, 10];
const expected = [11, 13, 15];
// Act
const result = Stream
.from(items)
.filter(i => i > 4)
.filter(i => i < 8)
.map(i => i * 2)
.map(i => i + 1)
.toArray();
// Assert
assert.deepEqual(result, expected);
})
});
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment