-
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:
-
_.assignInAllWith
has an order of(b, a)
-
_.assignInWith
has an order of(c, a, b)
-
_.assignAllWith
has an order of(b, a)
-
_.assignWith
has an order of(c, a, b)
-
_.differenceBy
has an order of(c, a, b)
-
_.differenceWith
has an order of(c, a, b)
-
_.getOr
has an order of(c, b, a)
-
_.intersectionBy
has an order of(c, a, b)
-
_.intersectionWith
has an order of(c, a, b)
-
_.isEqualWith
has an order of(c, a, b)
-
_.isMatchWith
has an order of(c, b, a)
-
_.mergeAllWith
has an order of(b, a)
-
_.mergeWith
has an order of(c, a, b)
-
_.padChars
has an order of(c, b, a)
-
_.padCharsEnd
has an order of(c, b, a)
-
_.padCharsStart
has an order of(c, b, a)
-
_.pullAllBy
has an order of(c, b, a)
-
_.pullAllWith
has an order of(c, b, a)
-
_.rangeStep
has an order of(c, a, b)
-
_.rangeStepRight
has an order of(c, a, b)
-
_.setWith
has an order of(d, b, c, a)
-
_.sortedIndexBy
has an order of(c, b, a)
-
_.sortedLastIndexBy
has an order of(c, b, a)
-
_.unionBy
has an order of(c, a, b)
-
_.unionWith
has an order of(c, a, b)
-
_.updateWith
has an order of(d, b, c, a)
-
_.xorBy
has an order of(c, a, b)
-
_.xorWith
has an order of(c, a, b)
-
_.zipWith
has an order of(c, a, b)
The iteratee 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:
-
_.F
is an alias of_.stubFalse
-
_.T
is an alias of_.stubTrue
-
_.__
is an alias of_.placeholder
-
_.all
is an alias of_.every
-
_.allPass
is an alias of_.overEvery
-
_.always
is an alias of_.constant
-
_.any
is an alias of_.some
-
_.anyPass
is an alias of_.overSome
-
_.apply
is an alias of_.spread
-
_.assoc
is an alias of_.set
-
_.assocPath
is an alias of_.set
-
_.complement
is an alias of_.negate
-
_.compose
is an alias of_.flowRight
-
_.conforms
is an alias of_.conformsTo
-
_.contains
is an alias of_.includes
-
_.dissoc
is an alias of_.unset
-
_.dissocPath
is an alias of_.unset
-
_.dropLast
is an alias of_.dropRight
-
_.dropLastWhile
is an alias of_.dropRightWhile
-
_.eachRight
is an alias of_.forEachRight
-
_.entries
is an alias of_.toPairs
-
_.entriesIn
is an alias of_.toPairsIn
-
_.equals
is an alias of_.isEqual
-
_.extend
is an alias of_.assignIn
-
_.extendAll
is an alias of_.assignInAll
-
_.extendAllWith
is an alias of_.assignInAllWith
-
_.extendWith
is an alias of_.assignInWith
-
_.first
is an alias of_.head
-
_.identical
is an alias of_.eq
-
_.indexBy
is an alias of_.keyBy
-
_.init
is an alias of_.initial
-
_.invertObj
is an alias of_.invert
-
_.juxt
is an alias of_.over
-
_.matches
is an alias of_.isMatch
-
_.nAry
is an alias of_.ary
-
_.omitAll
is an alias of_.omit
-
_.path
is an alias of_.get
-
_.pathEq
is an alias of_.matchesProperty
-
_.pathOr
is an alias of_.getOr
-
_.paths
is an alias of_.at
-
_.pickAll
is an alias of_.pick
-
_.pipe
is an alias of_.flow
-
_.pluck
is an alias of_.map
-
_.prop
is an alias of_.get
-
_.propEq
is an alias of_.matchesProperty
-
_.propOr
is an alias of_.getOr
-
_.property
is an alias of_.get
-
_.props
is an alias of_.at
-
_.symmetricDifference
is an alias of_.xor
-
_.symmetricDifferenceBy
is an alias of_.xorBy
-
_.symmetricDifferenceWith
is an alias of_.xorWith
-
_.takeLast
is an alias of_.takeRight
-
_.takeLastWhile
is an alias of_.takeRightWhile
-
_.unapply
is an alias of_.rest
-
_.unnest
is an alias of_.flatten
-
_.useWith
is an alias of_.overArgs
-
_.where
is an alias of_.conformsTo
-
_.whereEq
is an alias of_.isMatch
-
_.zipObj
is 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);
// ➜ true
The 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.