Introduction to Lodash

Lodash is a JavaScript library which provides utility functions for dealing with javascript objects and arrays, enhancing productivity and code readability.
Lodash provides a plethora of functions, following are some of them that will help in solving the most common challenges when dealing with javascript objects.

_.map

Iterates over an array or properties of an object and returns a new array with values as the result of the callback function.

const numbers = [2, 5, 9];

_.map(numbers, num => num * 2);
// [ 4, 10, 18 ]

The above can be achieved through es5 map as well but _.map can be used in other ways. Like getting a specific property from an array of objects.

const data = [
  {
    name: 'Patrick',
    age: '25',
  },
  {
    name: 'John',
    age: '24',
  },
  {
    name: 'Teresa',
    age: '26',
  }
];

_.map(data, 'name');
// [ 'Patrick', 'John', 'Teresa' ]

Works with nested properties as well

const data = [
  {
    name: 'Patrick',
    age: '25',
    profile: {
      experience: 2
    }
  },
  {
    name: 'John',
    age: '24',
    profile: {
      experience: 2
    }
  },
  {
    name: 'Teresa',
    age: '26',
    profile: {
      experience: 4
    }
  }
];

_.map(data, 'profile.experience');
// [ 2, 2, 4 ]

Similar useful functions: _.mapValues, _.mapKeys, _.flatMap

_.find

Iterates over elements of collection, returning the first element predicate returns truthy for.

const users = [
  {
    name: 'Patrick', age: '25', profile: { experience: 2 }
  },
  {
    name: 'John', age: '24', profile: { experience: 2 }
  },
  {
    name: 'Teresa', age: '26', profile: { experience: 4 }
  }
];

_.find(users, user => user.name === 'John');
// { name: 'John', age: '24', profile: { experience: 2 } }

Similar useful functions: _.findIndex, _.some

_.filter

Iterates over elements of collection, returning an array of all elements predicate returns truthy for.

For example, we want to filter the array of objects based on the profile.experience property.

const users = [
  {
    name: 'Patrick', age: '25', profile: { experience: 3 }
  },
  {
    name: 'John', age: '24', profile: { experience: 2 }
  },
  {
    name: 'Teresa', age: '26', profile: { experience: 4 }
  }
];

_.filter(users, user => user.profile.experience > 2);
// [ { name: 'Patrick', age: '25', profile: { experience: 3 } },
//   { name: 'Teresa', age: '26', profile: { experience: 4 } } ]

Similar useful functions: _.every

_.keyBy

Creates an object composed of keys generated from the results of running each element of collection through the callback function.

We can convert an array of objects into a single object having properties as the unique identifier of each object. This way we can easily access the object based on that unique identifier.

const users = [
  {
    name: 'Patrick', age: '25', profile: { experience: 2 }
  },
  {
    name: 'John', age: '24', profile: { experience: 2 }
  },
  {
    name: 'Teresa', age: '26', profile: { experience: 4 }
  }
];

const usersByName = _.keyBy(users, 'name');

usersByName['Teresa'];
// { name: 'Teresa', age: '26', profile: { experience: 4 } }

Similar useful functions: _.groupBy

_.get

Gets the value at path of object. If the resolved value is undefined, the defaultValue is returned in its place.

Normally in javascript, to get a nested property of an object, we have to write something like the following:

const experience = user && user.profile && user.profile.experience ? user.profile.experience : 0;

Very common use case, using _.get not only makes the code more readable but also avoids annoying errors like cannot read property 'experience' of undefined .

const experience = _.get(user, 'profile.experience', 0);

Similar useful functions: _.set

_.cloneDeep

This method recursively clones the whole object, so if any property of the resultant object changes, it will not change the original object as the references will also be new.

const users = [
  {
    name: 'Patrick', age: '25', profile: { experience: 3 }
  },
  {
    name: 'John', age: '24', profile: { experience: 2 }
  },
  {
    name: 'Teresa', age: '26', profile: { experience: 4 }
  }
];

const usersClone = _.cloneDeep(users);
usersClone[0].age = '27';

usersClone[0].age;
// 27
users[0].age;
// 25

Goodbye to code likeJSON.parse(JSON.stringify(obj)) .

Note: _.forEach, _.reduce, _.assign are some of the functions I skipped since they pretty much work the same as their ES5/6 counterparts. If these don’t sound familiar, you should definitely check them out.

Function chaining

_.chain can be used to chain functions together as follows:

const users = [
  {
    name: 'Patrick', age: 25, profile: { experience: 3 }
  },
  {
    name: 'John', age: 24, profile: { experience: 2 }
  },
  {
    name: 'Teresa', age: 26, profile: { experience: 4 }
  }
];

_.chain(users)
 .map('age')
 .mean()
 .value();
// 25

This way code becomes much more readable.

One downfall with .chain is that we cannot use user-defined functions on the object returned by it. But lodash does give a way to do it by using **.mixin** as shown in the following:

const users = [
  {
    name: 'Patrick', age: 25, profile: { experience: 3 }
  },
  {
    name: 'John', age: 24, profile: { experience: 2 }
  },
  {
    name: 'Teresa', age: 26, profile: { experience: 4 }
  }
];

const multiplyByTwo = numbers => _.map(numbers, num => num * 2);

_.mixin({ multiplyByTwo });

_.chain(users)
 .map('age')
 .multiplyByTwo()
 .mean()
 .value();
// 50

Conclusion

Lodash as a javascript utility library provides many useful functions that one needs to deal with arrays, numbers, objects, strings, etc.

At the time of writing, it is the most depended upon package on npm. So rest assured while using it as it is one of the most well-maintained libraries.

References: https://lodash.com/docs/4.17.11

#Lodash #JavaScript #WebDev

Introduction to Lodash
3.45 GEEK