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.Installation
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');
Mapping
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.
Capped Iteratee Arguments
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, & timesMethods that cap iteratees to two arguments:
reduce, reduceRight, & transformThe iteratee of
mapKeys is capped to one argument: (key)Fixed Arity
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, & zipAllMethods 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, & zipObjectDeepMethods 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, & zipWithMethods with a fixed arity of four:
fill, setWith, & updateWithNo Optional Arguments
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' }]
Rearranged Arguments
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']
Most methods follow these rules
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)Exceptions to the rules
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, & zipAllMethods 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, & zipObjectDeepMethods 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)New Methods
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, & zipAllAliases
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
Placeholders
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); // ➜ true
Chaining
The
lodash/fp module does not convert chain sequence method on using functional composition as an alternative to method chaining.Convert
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());
Tooling
Use eslint-plugin-lodash-fp to help use
lodash/fp more efficiently.