Lodash is a very useful utility library that lets us work with objects and arrays easily.
However, now that the JavaScript standard library is catching up to libraries such as Lodash, we can implement many of the functions in simple ways.
In this article, we’ll look at how to implement Lodash methods that deal with combining items in a collection.
reduce
The Lodash reduce
method combines the values in a collection into one value by calling the iteratee
function, which takes an accumulator
parameter with the values that are combined so far and the 2nd parameter is the item to be combined for the array version.
The object version takes the result
, which has the accumulated value, value
, which has the value of the object, and key
which has the key of the object that’s being processed.
It also takes an optional accumulator
object with the initial value of the accumulator
parameter before iteratee
is run.
Then we can write the following code:
const reduce = (collection, iteratee, accumulator) => {
if (Array.isArray(collection)) {
return collection.reduce(iteratee, accumulator)
} else {
let reduced = accumulator;
for (const key of Object.keys(collection)) {
iteratee(reduced, collection[key], key)
}
return reduced;
}
}
In the code above, we check if collection
is an array. If it is, then we call reduce
on the array instance with the iteratee
function as the callback and the accumulator
as the initial value.
Otherwise, we create a new reduced
variable with the accumulator
as the initial value.
Then we loop through the keys of the collection
object with the iteratee
, which takes the reduced
value, the value of the given key and the key itself as the arguments.
We then return the reduced
object, which has the combined results.
Then we can call it as follows:
const result = reduce({
'a': 1,
'b': 2,
'c': 1
}, (result, value, key) => {
(result[value] || (result[value] = [])).push(key);
return result;
}, {});
In the code above, we called our own reduce
method with an object and a iteratee
function with the result
, value
, and key
parameters. Then in the function, we combined the values by populating the keys of the resulting object with the value
and push the keys into the array.
Then we get:
{
"1": [
"a",
"c"
],
"2": [
"b"
]
}
as the value of result
.
We can also call our reduce
function with an array as follows:
const result = reduce([1, 2], (sum, n) => {
return sum + n;
}, 0);
Then we get that result
is 3.
Photo by Brett Jordan on Unsplash
reduceRight
The reduceRight
method is similar to reduce
except that the values are combined from the end to the start.
We can implement it in a similar way to reduce
as follows:
const reduceRight = (collection, iteratee, accumulator) => {
if (Array.isArray(collection)) {
return collection.reverse().reduce(iteratee, accumulator)
} else {
let reduced = accumulator;
const keys = Object.keys(collection)
for (let i = keys.length - 1; i >= 0; i--) {
iteratee(reduced, collection[keys[i]], keys[i])
}
return reduced;
}
}
In the code above, in the array case, we reversed the array by calling reduce
with the same arguments as the reduce
implementation.
Otherwise, we loop through the object’s keys in reverse order. In the loop, we call iteratee
on each item. The iteraee
function takes the same parameters as the one we pass into reduce
.
We can call reduceRight
as follows:
const result = reduceRight({
'a': 1,
'b': 2,
'c': 1
}, (result, value, key) => {
(result[value] || (result[value] = [])).push(key);
return result;
}, {});
Then we get that result
is:
{
"1": [
"c",
"a"
],
"2": [
"b"
]
}
since we looped through object entries in reverse order.
We can call reduceRight
with an array as follows:
const result = reduceRight([1, 2], (sum, n) => {
return sum + n;
}, 0);
Then we get the same result as reduce
, which is 3.
Conclusion
The reduce
and reducerRight
methods can be done with existing array methods for arrays. We can just call reduce
on the array instance with the iteratee
function and the accumulator
.
For objects, it’s more complex. We have to loop through the items by getting the keys and the pass the keys and values into the iteratee
function, which takes the result
as the first argument. The second argument is the value
and the 3rd is the key
.