This article is also available in Urdu
I found a year old issue for my personal project that is to
Remove lodash dependency
I scanned the code to find following instances
import forIn from 'lodash-es/forIn';
import groupBy from 'lodash-es/groupBy';
import reduce from 'lodash-es/reduce';
import { sortBy, take } from 'lodash-es';I am even using the es modules that are much more performant that common js and what not is out there.
Let’s see how it’s used in our code base and what is the native alternative
groupBy
const grouped = groupBy(values, (item) =>
item.category.title ? item.category.title : item.category
);
JavaScrip has it’s own static method with same name of groupBy. Relatively same api, I wonder how much it’s inspired from lodash
Let’s see how we can replace it with built it solution
const grouped = Object.groupBy(values, (v => v.category?.title ?? v.category ))
We have even shortened it with optional chaining and nullish coalescing which also the readability but I think little sprinkles of it are okay
forIn
forIn(grouped, (value, key, item) => {
this.chartLabels.push(key.toUpperCase());
this.chartData.push(reduce(value, (sum, n) => sum + Number(n.price), 0));
});
So we are looping over object keys and pushing to dedicated array. I don’t how I went with forIn because for In was for ever supported. May by lodash version is less verbose and might have better ergonomics
Let’s replace it
for (const key in grouped) {
const element = grouped[key];
this.chartLabels.push(key.toUpperCase());
this.chartData.push(reduce(element, (sum, n) => sum + Number(n.price), 0));
}reduce
this.chartData.push(reduce(value, (sum, n) => sum + Number(n.price), 0));We have already seen the reduce in previous section of groupBy. Again Arrays has reduce for years and it’s very intuitive api.
//...
if(element) {
this.chartData.push(element.reduce((sum, n) => sum + Number(n.price), 0));
}
//...take
take(values, 3).map(item => {
chartLabels.push(item.key.toUpperCase());
chartData.push(item.value);
})Again here take, how different it could be from slice that ideally returns new array. But it doesn’t matter for array of object they are passed by references
slice(0, 3).map(item => {
chartLabels.push(item.key.toUpperCase());
chartData.push(item.value);
})Any way the replaced solution is slice(start, end) where end is not included. So starting from 0 it goes till 2.
sortBy
map(values => sortBy(values, 'key')),So this one has very nice ergonomics as well, all we have to is provide a key as string like key here or and array of strings as ['age', 'name'] as well as function. It also consider the Stable Sort that preserves the original sort order of equal elements.
map(values => values.toSorted((a, b) => a.key.localeCompare(b.key))),
The toSorted take care of stable sort by default but it gets a bit bloated and we always has to provide the function that decides how to sort, it a bit weird to define the logic.
We have found all those alternatives to loadash. Lodash has it place and it’s perfect tool if you need a lot of such manipulation with Array and object. As it’s already well tested, we can simply use it as utility library as tailwind for CSS has found it’s place
Fun fact why JavaScript array has includes a much common name is contains but they couldn’t go with name as it could broke the web as it was already taken by underscore.js
