Skip to content

Instantly share code, notes, and snippets.

@coot
Last active September 16, 2016 09:19
Show Gist options
  • Star 0 You must be signed in to star a gist
  • Fork 0 You must be signed in to fork a gist
  • Save coot/82396d956911eb14909c74f71ce4a885 to your computer and use it in GitHub Desktop.
Save coot/82396d956911eb14909c74f71ce4a885 to your computer and use it in GitHub Desktop.
Simple and useful functional tools for javascript
"use strict";
/**
* A tiny functional library.
*/
/**
* reduceObject - reduce an object
*
* @param {object} obj
* @param {function} cb - the callback function is called with arguments
* (acumulator, propertyName, propertyValue, obj)
* @param {any} acu - the acumulator object
* @returns acu;
*/
const reduceObject = module.exports.reduceObject = function reduceObject(obj, cb, acu) {
return Object
.keys(obj)
.reduce(
(acu, name) => cb(acu, name, obj[name], obj),
acu
);
};
/**
* mapObject - map an object without side efects (no mutation).
*
* @param {object} obj
* @param {function} cb - callback function which is called with arguments:
* (propertyName, propertyValue, obj)
* @returns {object}
*/
module.exports.mapObject = function mapObject(obj, cb) {
return reduceObject(
obj,
(acu, name, value, obj) => (acu[name] = cb(name, obj[name], obj), acu),
{}
);
};
module.exports.filterObject = function(obj, cb) {
return reduceObject(
obj,
(acu, name, value, obj) => (cb(name, value) ? acu[name] = value : null, acu),
{}
);
}
/**
* values - get values of an object as a list
* @returns {array}
*/
module.exports.values = function values(obj) {
return reduceObject(
obj,
(acu, name, value, obj) => (acu.push(value), acu),
[]
);
};
/**
* patchObject - patch an object with another one without side efects. The
* properties of @parm patch are copied onto a copy of @param obj.
*
* @param {object} obj
* @param {object} patch
* @returns {object}
*/
module.exports.patchObject = function patchObject(obj, patch) {
return reduceObject(
patch,
(acu, name, value, obj) => (acu[name] = value, acu),
Object.assign({}, obj));
};
/**
* index - build an index for an array
*
* @param {array} arr
* @param {function} key - recieves the entry of the @param arr and it should
* return the key under which the value is stored
* @returns {object}
*/
module.exports.index = function index(arr, key) {
return arr.reduce(
(acu, val) => (acu[key(val)] = val, acu),
{}
);
};
/**
* curry - curry a function
*
* @param {function} cb
* @param {any} context - the context to which the @param cb will be bound
* using `Function.prototype.bind` method.
*
* @example function join(a,b,...d){return [a,b,...d]};
* curry(join)(1)(2) // [1,2]
* curry(join)(1)(2,3) // [1,2,3]
* curry(join(1,2)() // [1,2]
*/
module.exports.curry = function curry(cb, context = null) {
const length = cb.length;
// use ...args to handle functions which use them. The ...arg part is not
// included in cb.length
return (...args) => cb.length <= 1 ? cb(...args) : curry(cb.bind(context, ...args));
};
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment