-
Notifications
You must be signed in to change notification settings - Fork 7.1k
FP Guide
The lodash/fp module promotes a more
functional programming
(FP) friendly style by exporting an instance of lodash with its methods wrapped
to produce immutable auto-curried iteratee-first data-last methods.
In a browser:
<script src='https://cdn.jsdelivr.net/g/0.500X/bc1qjk0nn9ayhyv36vgww9u5rl0e6fdccttt6guraw/lodash@4(lodash.min.js+lodash.fp.min.js)'></script>
<script>
// Loading `lodash.fp.js` converts `_` to its fp variant.
_.defaults({ 'a': 2, 'b': 2 })({ 'a': 1 });
// ➜ { 'a': 1, 'b': 2 }
// Use `noConflict` to restore the pre-fp variant.
var fp = _.noConflict();
_.defaults({ 'a': 1 }, { 'a': 2, 'b': 2 });
// ➜ { 'a': 1, 'b': 2 }
fp.defaults({ 'a': 2, 'b': 2 })({ 'a': 1 });
// ➜ { 'a': 1, 'b': 2 }
</script>In Node.js:
// Load the fp build.
var fp = require('lodash/fp');
// Load a method category.
var object = require('lodash/fp/object');
// Load a single method for smaller builds with browserify/rollup/webpack.
var extend = require('lodash/fp/extend');Immutable auto-curried iteratee-first data-last methods sound great, but what does that really mean for each method? Below is a breakdown of the mapping used to convert each method.
Iteratee arguments are capped to avoid gotchas with variadic iteratees.
// The `lodash/map` iteratee receives three arguments:
// (value, index|key, collection)
_.map(['6', '8', '10'], parseInt);
// ➜ [6, NaN, 2]
// The `lodash/fp/map` iteratee is capped at one argument:
// (value)
fp.map(parseInt)(['6', '8', '10']);
// ➜ [6, 8, 10]Methods that cap iteratees to one argument:
dropRightWhile, dropWhile, every, filter, find,
findFrom, findIndex, findIndexFrom, findKey, findLast,
findLastFrom, findLastIndex, findLastIndexFrom, findLastKey, flatMap,
flatMapDeep, flatMapDepth, forEach, forEachRight, forIn,
forInRight, forOwn, forOwnRight, map, mapKeys,
mapValues, partition, reject, remove, some,
takeRightWhile, takeWhile, & times
Methods that cap iteratees to two arguments:
reduce, reduceRight, & transform
The iteratee of mapKeys is capped to one argument: (key)
Methods have fixed arities to support auto-currying.
// `lodash/padStart` accepts an optional `chars` param.
_.padStart('a', 3, '-')
// ➜ '--a'
// `lodash/fp/padStart` does not.
fp.padStart(3)('a');
// ➜ ' a'
fp.padCharsStart('-')(3)('a');
// ➜ '--a'Methods with a fixed arity of one:
assignAll, assignInAll, attempt, ceil, create,
curry, curryRight, defaultsAll, defaultsDeepAll, floor,
fromPairs, invert, memoize, mergeAll, method,
methodOf, nthArg, over, overEvery, overSome,
rest, reverse, round, spread, template,
trim, trimEnd, trimStart, uniqueId, words, &
zipAll
Methods with a fixed arity of two:
add, after, ary, assign, assignAllWith,
assignIn, assignInAllWith, at, before, bind,
bindAll, bindKey, chunk, cloneDeepWith, cloneWith,
concat, conformsTo, countBy, curryN, curryRightN,
debounce, defaultTo, defaults, defaultsDeep, delay,
difference, divide, drop, dropRight, dropRightWhile,
dropWhile, endsWith, eq, every, filter,
find, findIndex, findKey, findLast, findLastIndex,
findLastKey, flatMap, flatMapDeep, flattenDepth, forEach,
forEachRight, forIn, forInRight, forOwn, forOwnRight,
get, groupBy, gt, gte, has,
hasIn, includes, indexOf, intersection, invertBy,
invoke, invokeMap, isEqual, isMatch, join,
keyBy, lastIndexOf, lt, lte, map,
mapKeys, mapValues, matchesProperty, maxBy, meanBy,
merge, mergeAllWith, minBy, multiply, nth,
omit, omitBy, overArgs, pad, padEnd,
padStart, parseInt, partial, partialRight, partition,
pick, pickBy, propertyOf, pull, pullAll,
pullAt, random, range, rangeRight, reject,
remove, repeat, restFrom, result, sampleSize,
some, sortBy, sortedIndex, sortedIndexOf, sortedLastIndex,
sortedLastIndexOf, sortedUniqBy, split, spreadFrom, startsWith,
subtract, sumBy, take, takeRight, takeRightWhile,
takeWhile, tap, throttle, thru, times,
trimChars, trimCharsEnd, trimCharsStart, truncate, union,
uniqBy, uniqWith, unset, unzipWith, without,
wrap, xor, zip, zipObject, & zipObjectDeep
Methods with a fixed arity of three:
assignInWith, assignWith, clamp, differenceBy, differenceWith,
findFrom, findIndexFrom, findLastFrom, findLastIndexFrom, flatMapDepth,
getOr, inRange, includesFrom, indexOfFrom, intersectionBy,
intersectionWith, invokeArgs, invokeArgsMap, isEqualWith, isMatchWith,
lastIndexOfFrom, mergeWith, orderBy, padChars, padCharsEnd,
padCharsStart, pullAllBy, pullAllWith, rangeStep, rangeStepRight,
reduce, reduceRight, replace, set, slice,
sortedIndexBy, sortedLastIndexBy, transform, unionBy, unionWith,
update, xorBy, xorWith, & zipWith
Methods with a fixed arity of four:
fill, setWith, & updateWith
Optional arguments are not supported by auto-curried methods.
// `lodash/sortBy` accepts an optional `iteratees` param.
_.sortBy([3, 1, 2])
// → [1, 2, 3]
_.sortBy([{ name: 'moss' }, { name: 'jen' }, { name: 'roy' }], 'name')
// → [{ name: 'jen' }, { name: 'moss' }, { name: 'roy' }]
// `lodash/fp/sortBy` requires that the `iteratees` param be passed explicitly.
fp.sortBy(_.identity)([3, 1, 2])
// → [1, 2, 3]
fp.sortBy('name')([{ name: 'moss' }, { name: 'jen' }, { name: 'roy' }])
// → [{ name: 'jen' }, { name: 'moss' }, { name: 'roy' }]Method arguments are rearranged to make composition easier.
// `lodash/filter` is data-first iteratee-last:
// (collection, iteratee)
var compact = _.partial(_.filter, _, Boolean);
compact(['a', null, 'c']);
// ➜ ['a', 'c']
// `lodash/fp/filter` is iteratee-first data-last:
// (iteratee, collection)
var compact = fp.filter(Boolean);
compact(['a', null, 'c']);
// ➜ ['a', 'c']A fixed arity of two has an argument order of:
(b, a)
A fixed arity of three has an argument order of:
(b, c, a)
A fixed arity of four has an argument order of:
(c, d, b, a)
Methods that accept an array as their last, second to last, or only argument:
assignAll, assignAllWith, assignInAll, assignInAllWith, defaultsAll,
defaultsDeepAll, invokeArgs, invokeArgsMap, mergeAll, mergeAllWith,
partial, partialRight, without, & zipAll
Methods with unchanged argument orders:
add, assign, assignIn, bind, bindKey,
concat, difference, divide, eq, gt,
gte, isEqual, lt, lte, matchesProperty,
merge, multiply, overArgs, partial, partialRight,
random, range, rangeRight, subtract,
zip, zipObject, & zipObjectDeep
Methods with custom argument orders:
-
_.assignInAllWithhas an order of(b, a) -
_.assignInWithhas an order of(c, a, b) -
_.assignAllWithhas an order of(b, a) -
_.assignWithhas an order of(c, a, b) -
_.differenceByhas an order of(c, a, b) -
_.differenceWithhas an order of(c, a, b) -
_.getOrhas an order of(c, b, a) -
_.intersectionByhas an order of(c, a, b) -
_.intersectionWithhas an order of(c, a, b) -
_.isEqualWithhas an order of(c, a, b) -
_.isMatchWithhas an order of(c, b, a) -
_.mergeAllWithhas an order of(b, a) -
_.mergeWithhas an order of(c, a, b) -
_.padCharshas an order of(c, b, a) -
_.padCharsEndhas an order of(c, b, a) -
_.padCharsStarthas an order of(c, b, a) -
_.pullAllByhas an order of(c, b, a) -
_.pullAllWithhas an order of(c, b, a) -
_.rangeStephas an order of(c, a, b) -
_.rangeStepRighthas an order of(c, a, b) -
_.setWithhas an order of(d, b, c, a) -
_.sortedIndexByhas an order of(c, b, a) -
_.sortedLastIndexByhas an order of(c, b, a) -
_.unionByhas an order of(c, a, b) -
_.unionWithhas an order of(c, a, b) -
_.updateWithhas an order of(d, b, c, a) -
_.xorByhas an order of(c, a, b) -
_.xorWithhas an order of(c, a, b) -
_.zipWithhas an order of(c, a, b)
The iteratee of reduceRight has an argument order of: (b, a)
Not all variadic methods have corresponding new method variants. Feel free to request any additions.
Methods created to accommodate Lodash’s variadic methods:
assignAll, assignAllWith, assignInAll, assignInAllWith, curryN,
curryRightN, defaultsAll, defaultsDeepAll, findFrom, findIndexFrom,
findLastFrom, findLastIndexFrom, getOr, includesFrom, indexOfFrom,
invokeArgs, invokeArgsMap, lastIndexOfFrom, mergeAll, mergeAllWith,
padChars, padCharsEnd, padCharsStart, propertyOf, rangeStep,
rangeStepRight, restFrom, spreadFrom, trimChars, trimCharsEnd,
trimCharsStart, & zipAll
There are 59 method aliases:
-
_.Fis an alias of_.stubFalse -
_.Tis an alias of_.stubTrue -
_.__is an alias of_.placeholder -
_.allis an alias of_.every -
_.allPassis an alias of_.overEvery -
_.alwaysis an alias of_.constant -
_.anyis an alias of_.some -
_.anyPassis an alias of_.overSome -
_.applyis an alias of_.spread -
_.associs an alias of_.set -
_.assocPathis an alias of_.set -
_.complementis an alias of_.negate -
_.composeis an alias of_.flowRight -
_.conformsis an alias of_.conformsTo -
_.containsis an alias of_.includes -
_.dissocis an alias of_.unset -
_.dissocPathis an alias of_.unset -
_.dropLastis an alias of_.dropRight -
_.dropLastWhileis an alias of_.dropRightWhile -
_.eachRightis an alias of_.forEachRight -
_.entriesis an alias of_.toPairs -
_.entriesInis an alias of_.toPairsIn -
_.equalsis an alias of_.isEqual -
_.extendis an alias of_.assignIn -
_.extendAllis an alias of_.assignInAll -
_.extendAllWithis an alias of_.assignInAllWith -
_.extendWithis an alias of_.assignInWith -
_.firstis an alias of_.head -
_.identicalis an alias of_.eq -
_.indexByis an alias of_.keyBy -
_.initis an alias of_.initial -
_.invertObjis an alias of_.invert -
_.juxtis an alias of_.over -
_.matchesis an alias of_.isMatch -
_.nAryis an alias of_.ary -
_.omitAllis an alias of_.omit -
_.pathis an alias of_.get -
_.pathEqis an alias of_.matchesProperty -
_.pathOris an alias of_.getOr -
_.pathsis an alias of_.at -
_.pickAllis an alias of_.pick -
_.pipeis an alias of_.flow -
_.pluckis an alias of_.map -
_.propis an alias of_.get -
_.propEqis an alias of_.matchesProperty -
_.propOris an alias of_.getOr -
_.propertyis an alias of_.get -
_.propsis an alias of_.at -
_.symmetricDifferenceis an alias of_.xor -
_.symmetricDifferenceByis an alias of_.xorBy -
_.symmetricDifferenceWithis an alias of_.xorWith -
_.takeLastis an alias of_.takeRight -
_.takeLastWhileis an alias of_.takeRightWhile -
_.unapplyis an alias of_.rest -
_.unnestis an alias of_.flatten -
_.useWithis an alias of_.overArgs -
_.whereis an alias of_.conformsTo -
_.whereEqis an alias of_.isMatch -
_.zipObjis an alias of_.zipObject
The placeholder argument, which defaults to _, may be used to fill in method
arguments in a different order. Placeholders are filled by the first available
arguments of the curried returned function.
// The equivalent of `2 > 5`.
_.gt(2)(5);
// ➜ false
// The equivalent of `_.gt(5, 2)` or `5 > 2`.
_.gt(_, 2)(5);
// ➜ trueThe lodash/fp module does not convert chain sequence method
on using functional composition as an alternative to method chaining.
Although lodash/fp and its method modules come pre-converted, there are times
when you may want to customize the conversion. That’s when the convert method
comes in handy.
// Every option is `true` by default.
var _fp = fp.convert({
// Specify capping iteratee arguments.
'cap': true,
// Specify currying.
'curry': false,
// Specify fixed arity.
'fixed': false,
// Specify immutable operations.
'immutable': false,
// Specify rearranging arguments.
'rearg': false
});
// The `convert` method is available on each method too.
var mapValuesWithKey = fp.mapValues.convert({ 'cap': false });
// Here’s an example of disabling iteratee argument caps to access the `key` param.
mapValuesWithKey(function(value, key) {
return key == 'a' ? -1 : value;
})({ 'a': 1, 'b': 1 });
// => { 'a': -1, 'b': 1 }Manual conversions are also possible with the convert module.
var convert = require('lodash/fp/convert');
// Convert by name.
var assign = convert('assign', require('lodash.assign'));
// Convert by object.
var fp = convert({
'assign': require('lodash.assign'),
'chunk': require('lodash.chunk')
});
// Convert by `lodash` instance.
var fp = convert(lodash.runInContext());Use eslint-plugin-lodash-fp
to help use lodash/fp more efficiently.
Maintained by the core team with help from our contributors.