Navigation Menu

Skip to content

Instantly share code, notes, and snippets.

@bouzuya
Created June 19, 2016 05:54
Show Gist options
  • Star 2 You must be signed in to star a gist
  • Fork 0 You must be signed in to fork a gist
  • Save bouzuya/1a6b7c8d8c90dddc7f8e0f47beab7589 to your computer and use it in GitHub Desktop.
Save bouzuya/1a6b7c8d8c90dddc7f8e0f47beab7589 to your computer and use it in GitHub Desktop.
import * as assert from 'power-assert';
import beater from 'beater';
import { range, range2, take, fib, fib2, splitWord } from './generator';
const { test } = beater();
test('range()', () => {
const iterator = range(3);
assert.deepEqual(iterator.next(), { value: 0, done: false });
assert.deepEqual(iterator.next(), { value: 1, done: false });
assert.deepEqual(iterator.next(), { value: 2, done: false });
assert.deepEqual(iterator.next(), { value: undefined, done: true });
});
test('for(const i of range())', () => {
const array: number[] = [];
const iterable = range2(3); // !== iterator
for (const i of iterable) array.push(i);
assert.deepEqual(array, [0, 1, 2]);
});
test('Array.from', () => {
const array = Array.from(range2(3));
assert.deepEqual(array, [0, 1, 2]);
});
test('spread operator', () => {
const array = [...range2(3)];
assert.deepEqual(array, [0, 1, 2]);
const array2 = [...range2(3), ...range2(3), ...range2(3)];
assert.deepEqual(array2, [0, 1, 2, 0, 1, 2, 0, 1, 2]);
const f = (a: number, b: number, c: number): number[] => [a, b, c];
// const array3 = f(...range2(3)); // don't match signature
});
test('take()', () => {
assert.deepEqual(Array.from(take(range(1000), 5)), [0, 1, 2, 3, 4]);
assert.deepEqual(Array.from(take(range(3), 5)), [0, 1, 2]);
});
test('fib()', () => {
assert.deepEqual(Array.from(take(fib(), 6)), [1, 1, 2, 3, 5, 8]);
});
test('fib2()', () => {
assert.deepEqual(Array.from(take(fib2(), 6)), [1, 1, 2, 3, 5, 8]);
});
test('splitWord()', () => {
const array = Array.from(splitWord('Hello World Welcome To Generator'));
assert.deepEqual(array, ['Hello', 'World', 'Welcome', 'To', 'Generator']);
})
const range = (n: number): Iterator<number> => {
let value = 0;
return {
next: () => {
const curr = value;
const done = curr >= n;
if (!done) value += 1;
return { value: done ? undefined : curr, done };
}
};
};
const range2 = (n: number): Iterable<number> => {
return { [Symbol.iterator]: (): Iterator<number> => range(n) };
};
const range3 = (n: number): IterableIterator<number> => {
let value = 0;
return {
next: () => {
const curr = value;
const done = curr >= n;
if (!done) value += 1;
return { value: done ? undefined : curr, done };
},
[Symbol.iterator]() {
return this;
}
};
};
function* range4(n: number): IterableIterator<number> {
let i = 0;
while (i < n) {
yield i;
i += 1;
}
}
function* repeatRange(n: number, c: number): IterableIterator<number> {
while (c > 0) {
yield* range4(n);
c -= 1;
}
}
function range5(n: number): IterableIterator<number> {
function* f(i: number): IterableIterator<number> {
if (i < n) {
yield i;
yield* f(i + 1)
}
};
return f(0);
}
function* take(
iterator: Iterator<number>,
n: number
): IterableIterator<number> {
while (true) {
const d = iterator.next();
if (d.done || n <= 0) return;
n -= 1;
yield d.value;
}
};
function* fib(): IterableIterator<number> {
let a = [0, 1];
while (true) {
yield a[1];
a = [a[1], a[0] + a[1]];
}
};
function fib2(): IterableIterator<number> {
function* fib(p: number, c: number): IterableIterator<number> {
yield c;
yield* fib(c, p + c);
}
return fib(0, 1);
};
function* splitWord(s: string): IterableIterator<string> {
const m = s.match(/^(\S+)\s*(.*)$/);
if (!m) return;
yield m[1];
yield* splitWord(m[2]);
};
export { range, range2, range3, range4, take, fib, fib2, splitWord };
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment