Last active
June 5, 2019 09:25
-
-
Save tpoisseau/f0095249dfdeacbafc51f8af04b0aac1 to your computer and use it in GitHub Desktop.
Array.prototype rewrite in generator + some extra with functional tooling for pipe operator + polyfill with pipe function
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
/** | |
* Array.prototype rewrite for functional generator compatibilities + some extra | |
*/ | |
function* range({start=0, stop, step=1}) { | |
for (let i = start; i < stop; i+=step) { | |
yield i; | |
} | |
} | |
function* concat(...args) { | |
for (let arg of args) { | |
if (Array.isArray(arg)) yield * arg; | |
else yield arg; | |
} | |
} | |
function every(iterable, callback) { | |
for (let item of iterable) { | |
if (!callback(item)) return false; | |
} | |
return true; | |
} | |
function* filter(iterable, callback) { | |
for (let item of iterable) { | |
if (callback(item)) yield item; | |
} | |
} | |
function find(iterable, callback) { | |
for (let item of iterable) { | |
if (callback(item)) return item; | |
} | |
} | |
function* ennumerate(iterable) { | |
let index = 0; | |
for (let item of iterable) { | |
yield [index++, item]; | |
} | |
} | |
function findIndex(iterable, callback) { | |
for (let [index, item] of ennumerate(iterable)) { | |
if (callback(item)) return index; | |
} | |
} | |
function forEach(iterable, callback) { | |
for (let item of iterable) { | |
callback(item); | |
} | |
} | |
function includes(iterable, value) { | |
for (let item of iterable) { | |
if (item === value) return true; | |
} | |
return false; | |
} | |
function indexOf(iterable, value) { | |
for (let [index, item] of ennumerate(iterable)) { | |
if (item === value) return index; | |
} | |
return -1; | |
} | |
function join(iterable, joiner) { | |
let result = ''; | |
for (let item of iterable) { | |
result += item + joiner; | |
} | |
return result.substr(0, result.length - joiner.length); | |
} | |
function* map(iterable, callback) { | |
for (let item of iterable) { | |
yield callback(item); | |
} | |
} | |
function* shift(iterable, position=1) { | |
for (let [index, item] of ennumerate(iterable)) { | |
if (index >= position) yield iterable; | |
} | |
} | |
function* reverse(iterable) { | |
yield * Array.from(iterable).reverse(); | |
} | |
function* slice(iterable, {start=0, stop, step=1}) { | |
for (let [index, item] of ennumerate(iterable)) { | |
if (index < debut) continue; | |
if (index >= stop) continue; | |
if ((index % step) !== 0) continue; | |
yield item; | |
} | |
} | |
function some(iterable, callback) { | |
for (let item of iterable) { | |
if (callback(item)) return true; | |
} | |
return false; | |
} | |
function reduce(iterable, callback, initValue=0) { | |
for (let item of iterable) { | |
initValue = callback(initValue, item); | |
} | |
return initValue; | |
} | |
function* flat(iterable) { | |
yield * reduce(iterable, (acc, val) => concat(acc, val), []) | |
} | |
/** | |
* functional API | |
*/ | |
function partial(callback, ...cachedArgs) { | |
return (...args) => callback(...cachedArgs, ...args) | |
} | |
function partialRight(callback, ...cachedArgs) { | |
return (...args) => callback(...args, ...cachedArgs); | |
} | |
function construct(Type, ...args) { | |
return new Type(...args); | |
} | |
function pipe(value, ...operations) { | |
for (let [index, op] of ennumerate(operations)) { | |
value = op(value); | |
} | |
return value; | |
} | |
reduce([ | |
concat, every, filter, find, ennumerate, findIndex, forEach, includes, | |
indexOf, join, map, shift, reverse, slice, some, reduce, flat, range, | |
], (acc, value) => { | |
acc[value.name] = partial(partialRight, value); | |
return acc; | |
}, pipe); | |
pipe.construct = Type => (it => construct(Type, it)); | |
module.exports = { | |
// generators | |
concat, every, filter, find, ennumerate, findIndex, forEach, includes, | |
indexOf, join, map, shift, reverse, slice, some, reduce, flat, range, | |
// functional | |
partial, partialRight, pipe, | |
}; | |
/* | |
const itools = require('./index.js'); | |
const {pipe} = itools; | |
const result = pipe( | |
itools.range({stop: 100}), | |
pipe.map(v => v * Math.random()), | |
pipe.map(Math.floor), | |
pipe.filter(v => v % 2), | |
pipe.construct(Set), | |
itools.ennumerate, | |
pipe.reduce((map, [index, value]) => map.set(index, value), new Map()), | |
map => map.entries(), | |
pipe.map(([k, v]) => `${k}:${v}`), | |
pipe.join(', ') | |
); | |
console.log(result); | |
*/ |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment