Categories
Lodash

Learning JavaScript by Implementing Lodash Methods — Combining Values

Spread the love

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 .

By John Au-Yeung

Web developer specializing in React, Vue, and front end development.

Leave a Reply

Your email address will not be published. Required fields are marked *