Categories
Lodash

Learning JavaScript by Implementing Lodash Methods — Grouping Items

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 grouping items in a collection.

keyBy

They keyBy method groups collection entries into keys as returned by a function that takes an entry as the parameter and returns the key according to what’s in the function’s code.

We can create our own keyBy function as follows:

const keyBy = (arr, fn) => {
  let obj = {};
  for (const a of arr) {
    obj[fn(a)] = a;
  }
  return obj;
}

In the code above, we just created an empty object, then populated it by calling fn with the array entry from the for...of loop and use it as the key.

Then the corresponding array entry is set as the value, and the object is returned.

When we call it as follows:

const arr = [{
    'dir': 'left',
    'code': 99
  },
  {
    'dir': 'right',
    'code': 100
  }
];
const result = keyBy(arr, o => String.fromCharCode(o.code))

Then result is:

{
  "c": {
    "dir": "left",
    "code": 99
  },
  "d": {
    "dir": "right",
    "code": 100
  }
}{
  "c": {
    "dir": "left",
    "code": 99
  },
  "d": {
    "dir": "right",
    "code": 100
  }
}

map

The map method returns an array that is mapped from the original array by calling a function on each entry and putting it in the new array.

Since the plain JavaScript has a map method for array instances, we can just use it to implement the Lodash map method.

Lodash’s map method also takes an object as an argument, which takes the keys and then maps the values with a function and put the values in the returned array.

We can implement this as follows:

const map = (collection, iteratee) => {
  if (Array.isArray(collection)){
    return collection.map(iteratee);
  }
  else {
    return Object.values(collection).map(iteratee)
  }
}

In the code above, we use the Array.isArray method to check if collection is an array. If it is, then we just use the array’s map method and use iteratee as the callback.

Otherwise, we use Object.values to return an array of object values and call map with iteratee as the callback on it.

Then we can call it as follows:

const result = map([4, 8], x => x**2);

which sets result to:

[
  16,
  64
]

Also, when we run:

const result = map({ 'a': 4, 'b': 8 }, x => x**2);

We get the same result.

partition

The partition method returns an array that’s grouped by the key returned by the function that’s passed in.

It groups an array by the key that’s returned by the function.

We can implement it as follows:

const partition = (collection, predicate) => {
  let obj = {};
  for (const a of collection) {
    if (!Array.isArray(obj[predicate(a)])) {
      obj[predicate(a)] = [];
    }
    obj[predicate(a)].push(a);
  }
  return Object.keys(obj).map(k => obj[k])
}

In the code above, we created an obj object, and then we loop through the collection with a for...of loop.

Then we create an array on with the key of obj that’s created by calling predicate on an entry.

If it’s not an array, then we set it to an empty array. Then we push the items according to the keys.

Finally, we return the values in an array by mapping the keys to the corresponding values.

Then when we call it as follows:

const users = [{
    'user': 'foo',
    'active': false
  },
  {
    'user': 'bar',
    'active': true
  },
  {
    'user': 'baz',
    'active': false
  }
];

const result = partition(users, o => o.active);

We get that result is:

[
  [
    {
      "user": "foo",
      "active": false
    },
    {
      "user": "baz",
      "active": false
    }
  ],
  [
    {
      "user": "bar",
      "active": true
    }
  ]
]

Conclusion

The keyBy method can be implemented by grouping the collections into an object with the for...of loop and populating the keys by calling the iteratee function. Then the values are populated by the corresponding key.

The map method can be implemented by the array instance’s map method.

partition can also be implemented by looping through all the objects and then populating the keys by calling the predicate with the array entry, and then we push the items into the array with the corresponding 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 *