Curried
Awesome curried standard library.
![browser support](https://ci.testling.com/hughfdjackson/curried.png)
Installation
In your project folder:
npm install curried --save
In a file:
var _ = require('curried');
API
FUNCTION
Functions that produce functions - the heart of the library in many senses!
curry
Lifted directly from npm curry; this is the function this library uses to produce its own curried functions.
compose
Chains together functions from right to left, passing the value each function produces into the next:
var appendWithHellYea = function(str){ return str + 'hell yea!' };
var appendSpace = function(str){ return str + ' ' };
var shout = function(str){ return str.toUpperCase() };
var hellYea = _.compose(appendWithHellYea, appendSpace, shout);
hellYea('functions!')
The above code is the same as appendWithHellYea(appendSpace(shout('functions!')))
pipe
To a whole lot of people, compose looks backwards. Pipe is compose the 'right way around', sorta like unix pipes.
var appendWithHellYea = function(str){ return str + 'hell yea!' };
var appendSpace = function(str){ return str + ' ' };
var shout = function(str){ return str.toUpperCase() };
var hellYea = _.pipe(shout, appendSpace, appendWithHellYea);
hellYea('functions!')
negate
Returns a function that returns false
when the original returned true
, and vice versa.
var isTruthy = function(a){ return !!a };
var isFalsey = _.negate(isTruthy);
isFalsey(0)
isFalsey(1)
isFalsey('')
isFalsey('abc')
isFalsey({})
flip
Returns a function with the argument order flipped
var prependWith = _.curry(function(a, b){ return a + b });
var appendWith = _.flip(prependWith);
var appendIsm = appendWith('ism');
appendIsm('functional')
identity
Returns the value passed into it.
var o = {}
_.identity(o) === o
In the functional world - where a function is often passed in to do some processing - it's the equivalent of a no-op.
var passCollectionThrough = _.map(_.identity);
passCollectionThrough([1, 2, 3])
var pointlesslyComplexIdentity = _.compose(_.identity, _.identity, _.identity);
pointlesslyComplexIdentity('a')
tap
If you're writing composition-heavy code, sometime's it's really important to be able to inject a step in the middle for debugging purposes.
var log = _.tap(function(value){ console.log(value) });
var shout = _.invoke('toUpperCase');
var appendWith = _.curry(function(a, b){ return b + a });
_.pipe(shout, log, appendWith('!'))('log this')
constant
Creates a function that always returns the same value.
constant('a')()
This can be particularly useful if you're expected to return a function, but really just want a value. For instance, handling values in promise chains:
getUserFromDB('bob smith')
.then(null, _.constant('john doe'))
.then(console.log)
COLLECTION
Collection functions work on Arrays AND objects.
map
var mapInc = _.map(function(a){ return a + 1 });
mapInc([1, 2, 3])
mapInc({ x: 1, y: 2, z: 3 })
filter
var isString = function(a){ return typeof a === 'string' };
var filterString = _.filter(isString);
filterString([1, 2, 'a', 3, 'b'])
filterString({ x: 1, y: 2, z: 'a', a: 3, b: 'b' })
reject
var isString = function(a){ return typeof a === 'string' };
var filterNotString = _.reject(isString);
filterNotString([1, 2, 'a', 3, 'b'])
filterNotString({ x: 1, y: 2, z: 'a', a: 3, b: 'b' })
every
var isString = function(a){ return typeof a === 'string' };
var allString = _.every(isString);
allString([1, 2, 'a', 3, 'b'])
allString(['a', '3', 'b'])
allString({ x: 1, y: 2, z: 'a' })
allString({ x: '1', y: 'b', z: 'a' })
some
var isString = function(a){ return typeof a === 'string' };
var someString = _.some(isString);
someString([1, 2, 'a', 3, 'b'])
someString([3, 4])
someString({ x: 1, y: 2, z: 'a' })
someString({ x: 1, y: 2, z: 3 })
reduce
var cat = _.reduce(function(a, b){ return a + b });
cat(['a', 'b', 'c'])
Since objects don't have guaranteed order in ECMAScript, it's only safe to reduce over objects with operations
that don't need arguments in any particular order (commutative).
var sum = _.reduce(function(a, b){ return a + b });
sum({ x: 1, y: 2, z: 3 })
reduceRight
var reverseCat = _.reduceRight(function(a, b){ return a + b });
reverseCat(['a', 'b', 'c'])
var sum = _.reduceRight(function(a, b){ return a + b });
sum({ x: 1, y: 2, z: 3 })
reduceFrom
var catWithPrefix = _.reduceFrom(function(a, b){ return a + b }, 'super awesome ');
catWithPrefix(['a', 'b', 'c'])
var sumFrom3 = _.reduceFrom(function(a, b){ return a + b }, 3);
sumFrom3({ x: 1, y: 2, z: 3 })
reduceRightFrom
var reverseCatWithPrefix = _.reduceRightFrom(function(a, b){ return a + b }, 'super awesome ');
reverseCatWithPrefix(['a', 'b', 'c'])
var sumFrom3 = _.reduceRightFrom(function(a, b){ return a + b }, 3);
sumFrom3({ x: 1, y: 2, z: 3 })
OBJECT
Works on objects - or things that act like an object (i.e. have properties).
invoke
var toString = _.invoke('toString');
['abc', 1, true, {}].map(toString)
invokeWith
var mapInc = _.invokeWith('parse', [function(a){ return a + 1 }]);
mapInc([1, 2, 3])
get
var getX = _.get('x');
getX({ x: 2 })
pick
var pick2DCoords = _.pick(['x', 'y']);
var coords3D = { x: 1, y: 2, z: 200 };
pick2DCoords(coords3D)
combine
var defaults = _.combine({ firstName: 'joe', lastName: 'bloggs' });
defaults({ lastName: 'shufflebottom'}
keys
_.keys({ x: 1, y: 2, z: 3 })
values
_.values({ x: 1, y: 2, z: 3 })
ARRAY
For those functions that only make sense with an ordered list.
take
var take5 = _.take(5);
take5([1, 2, 3, 4, 5, 6, 7, 8, 9, 10])
head
_.head([1, 2, 3])
_.head([])
tail
_.tail([1, 2, 3])
_.tail([1])
_.tail([])
initial
_.initial([1, 2, 3])
_.initial([1])
_.initial([])
last
_.last([1, 2, 3])
_.last([])