Skip to content

Instantly share code, notes, and snippets.

@tpoisseau
Last active June 5, 2019 09:25
Show Gist options
  • Save tpoisseau/f0095249dfdeacbafc51f8af04b0aac1 to your computer and use it in GitHub Desktop.
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
/**
* 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