Skip to content

Instantly share code, notes, and snippets.

@ughitsaaron
Last active April 15, 2020 16:39
Show Gist options
  • Save ughitsaaron/940482dcf1e3a0a3eea96f34de9ad12b to your computer and use it in GitHub Desktop.
Save ughitsaaron/940482dcf1e3a0a3eea96f34de9ad12b to your computer and use it in GitHub Desktop.
Functional utilities with generators
function range(start = 0, end, step = 1) {
function* rangeIter(start, end, step) {
if (start <= end) {
yield start;
let next = typeof step === 'function' ? step(start) : start + step;
yield* rangeIter(next, end, step);
}
}
return [...rangeIter(start, end, step)];
}
range(1, 1000, 2) // => [1, 3, 7...999]
range(1, 1000, x => x * 2)] // => [1, 2, 4...512]
function map(arr, fn) {
function* mapIter(arr, fn, i = 0) {
if (i <= arr.length - 1) {
yield fn(arr[i], i, arr);
yield* mapIter(arr, fn, i + 1);
}
}
return [...mapIter(arr, fn)];
}
map([1, 2, 3, 4, 5], x => x + 1); // => [2, 3, 4, 5, 6]
map(range(1, 1000, x => x * 2), x => x.toString()); // => ['1', '2', '4'...'512']
function cycle(arr, take = 0) {
function* cycleIter(arr, take, i = 0) {
if (take > 0) {
yield arr[i];
// if index is greater than array length, then start
// the cyle over.
yield* cycleIter(arr, take - 1, i + 1 >= arr.length ? 0 : i + 1);
}
}
return [...cycleIter(arr, take)];
}
cycle([1, 2, 3], 10) // => [1, 2, 3, 1, 2, 3, 1, 2, 3, 1]
map(cycle(range(2, 1000, x => x ** 2), 100), x => x + 1) // => [3, 5, 17, 257, 3, 5, 17, 257...]
@ughitsaaron
Copy link
Author

Some other utilities to add to this: filter, reduce/fold, find

@bmcmahen
Copy link

😮

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment