Last active
September 16, 2016 09:19
-
-
Save coot/82396d956911eb14909c74f71ce4a885 to your computer and use it in GitHub Desktop.
Simple and useful functional tools for javascript
This file contains 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
"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