JavaScript - Some very useful lodash/fp functions
Tags: javascript, lodash, functional, beginners
Published: 2021-06-09 19:59:47

If you still don't know [Lodash](https://lodash.com/), it's time for you to try it. Lodash is a modern JavaScript utility library that

> makes JavaScript easier by taking the hassle out of working with arrays, numbers, objects, strings, etc.

_Source: [https://lodash.com](https://lodash.com)_

It's okay if you prefer to deal with data types and structures the old fashion way by implementing your own algorithms, but I strongly believe that, in several cases, using Lodash will leverage your productivity and avoid some lines of code.

Besides, it is a very popular library, used by more then [10 million other projects on GitHub](https://github.com/lodash/lodash/network/dependents?package_id=UGFja2FnZS0xMzc4MTYwNA%3D%3D), and it's been downloaded more than [40 million times from NPM](https://www.npmjs.com/package/lodash).

Lodash also provides a [Functional Programming Module](https://github.com/lodash/lodash/wiki/FP-Guide), which, according to them:

>  promotes a more functional programming (FP) friendly style by exporting an instance of Lodash with its methods wrapped to produce immutable auto-curried iteratee-first data-last methods.

_Source: https://github.com/lodash/lodash/wiki/FP-Guide_

In this article I'm going to introduce some
 Lodash FP methods that will save some of your precious development hours by helping you to deal easily with different data structures in several situations.

---
## isEmpty
Let's start with one of the simplest methods of Lodash FP module. It is the `isEmpty` one.
This method provides you an easy way to verify if a variable is empty or not (really?! 😒). It works well for arrays, objects and strings. But take care when checking Boolean or Numeric values.

Take a look at the examples below:

```javascript
import { isEmpty } from 'lodash/fp'

// Empty array
isEmpty([]) // true

// Empty object
isEmpty({}) // true

// Empty string
isEmpty('') // true

// Null
isEmpty(null) // true

// Undefined
isEmpty(undefined) // true
```

Initially, `isEmpty` was designed to deal only with _arrays_, _objects_ and _strings_ so, when dealing with Boolean, numeric or Function values, you need to be a little bit more cautious because it will always return `true` for these types no matter what..

```javascript
// Numbers
isEmpty(0) // true - it seems okay depending on the context
isEmpty(2021) // true - wait, what?!

// Boolean
isEmpty(false) // true - this might make sense
isEmpty(true) // true - oh no, again?!

// Function
isEmpty(function() {}) // true - ok, I quit!
```

You can check its full implementation to understand why this happens [here](https://github.com/lodash/lodash/blob/master/isEmpty.js)

## get
The next method on our list is the `get` method.
It allows you to get (again, b*tch?!) values from objects or arrays that you're not sure if they're available. 
This helps a lot when dealing with dynamic structures within implementations that might continue even if specific values are not available at runtime.

Here are some examples:

```javascript
import { get } from 'lodash/fp' 

const aryaStark = {
  name: 'Arya Stark',
  age: 15,
  father: { name: 'Ned Start' },
  mother: { name: 'Catelyn Stark' }
}

const jonSnow = {
  name: 'Jon Snow',
  age: 30,
  father: { name: 'Ned Stark' },
  mother: null
}

get('mother.name', aryaStark) // 'Catelyn Stark'
get('mother.name', jonSnow) // undefined
```

**It's important to mention that, if the searched value is `null`, the result will be `null`**

You may use `get` to grab values regardless of the level the information is at within an object. For example:

```javascript
import { get } from 'lodash/fp' 

const jonSnow = {
  name: 'Jon Snow',
  parents: {
    father: {
      fullName: {
        firstName: 'Ned',
        lastName: 'Stark'
      }
    }
  }
}

get('parents.father.fullName.firstName', jonSnow) // 'Ned'

get('parents.mother.fullName.firstName', jonSnow) // undefined
```

You may also use `get` to get (😒) values from arrays by their indexes using the `[index]` notation. You might even combine the `.` and the `[index]` notations to grab data from complex structures.

```javascript
import { get } from 'lodash/fp' 

const characters = [
  {
     name: 'Jon Snow',
     house: 'Stark',
     parents: [
       'Ned Stark',
       'Unknown Mom (spoiler)'
     ]
  },
  {
    name: 'Jaime Lannister',
    house: 'Lannister',
    parents: [
      'Tywin Lannister', 
      'Joanna Lannister'
    ]
  },
  {
    name: 'Daenerys Targaryen',
    house: 'Targaryen',
    parents: [
      'Aerys II Targaryen',
      'Rhaella Targaryen'
    ]
  }
]

get('[1].parents[0]', characters) // 'Tywin Lannister'
```

This is how you deal with simple arrays:

```javascript
import { get } from 'lodash/fp' 

const evenNumbers = ['zero', 'two', 'four', 'six', 'eight']

get(3, evenNumbers) // 'six'
```

And last, but not least, you may also need to get dynamic properties according to a given variable:

```javascript
import { get } from 'lodash/fp' 

const activeUser = {
  name: 'John Doe',
  isActive: true,
  nickname: 'theUnknown'
}

const inactiveUser = {
  name: 'Jane Doe',
  isActive: false,
  nickname: 'someoneElse'
}


function getName(user) {
  const attr = user.isActive ? 'nickname' : 'name'
  return get(attr, user)
}

getName(activeUser) // 'theUnknown'
getName(inactiveUser) // 'Jane Doe'
```

## getOr
The `getOr` method increments a little bit what the `get` method does. The only difference here is that there is a third parameter that will be used in case of the property or index doesn't exist.

```javascript
import { getOr } from 'lodash/fp' 

const jaimeLannister = {
  name: 'Jaime Lannister',
  parents: {
    father: {
      fullName: {
        firstName: 'Tywin',
        lastName: 'Lannister'
      }
    }
  }
}

getOr('Joanna Lannister', 'parents.mother.fullName.firstName', jaimeLannister) // Joanna Lannister
```

It's important to keep in mind that, regardless of the attribute/item value, if it exists it will be returned.
The fallback value (first parameter) will **only** be used if the attribute or item searched does not exist or is `undefined`.

Check the example:

```javascript
import { getOr } from 'lodash/fp' 

const houseLannister = { name: 'Lannister' }
const houseStark = { name: 'Stark' }
const uknownHouse = { name: null }
const invalidHouse = {}

getOr('UnknownHouse', 'name', unknownHouse) // null
getOr('Invalid House', 'name', invalidHouse) // 'Invalid House'
```

If the intention is to get the value `'Unknown House'` in a situation like above, the correct way of doing it would be using `get`:

```javascript
import { getOr } from 'lodash/fp' 

const uknownHouse = { name: null }

get('name', uknownHouse) || 'Unknown House' // 'Unknown House'
```

You may also use `getOr` to grab data from arrays or even combine the object and array notations to get values from complex structures:

```javascript
import { getOr } from 'lodash/fp' 

const characters = [
  {
    name: 'John Snow',
    house: 'Stark',
    parents: [ 'Ned Stark' ]
  },
  {
    name: 'Jaime Lannister',
    house: 'Lannister',
    parents: [
      'Tywin Lannister',
     'Joanna Lannister'
    ]
  },
  {
    name: 'Daenerys Targaryen',
    house: 'Targaryen',
    parents: [
      'Aerys II Targaryen',
      'Rhaella Targaryen'
    ]
  }
]

getOr('Unknown Mom (spoiler)', '[0].parents[1]', characters) // 'Unknown Mom (spoiler)'
```

**Take a look at all `get` examples. You may implement all of them using `getOr` following the same logic.**

## at
The `at` method is quite useful when you need to get more than one attribute/index from the same object regardless of the level the information is. It will return an array containing all of the found values and `undefined` for those that weren't found. The coolest thing about it is that you can use the _[Destructuring Assignment](https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Operators/Destructuring_assignment)_ syntax and use the variables straight away:

```javascript
import { at } from 'lodash/fp'

const jaimeLannister = {
  firstName: 'Jaime',
  lastName: 'Lannister',
  father: {
    firstName: 'Tywin',
    lastName: 'Lannister'
  },
  mother: {
    firstName: 'Joanna',
    lastName: 'Lannister'
  }
}

at(['father.firstName', 'mother.firstName'], jaimeLannister) // ['Tywin', 'Joanna']

// Using Destructuring Assignment
const [father, mother] = at(['father.firstName', 'mother.firstName'], jaimeLannister)

console.log(father) // 'Tywin'
console.log(mother) // 'Joanna'
```

The same rule to get items from arrays using their indexes with `get` or `getOr` is applied for `at`.

```javascript
import { at } from 'lodash/fp'

const characters = [
  {
    name: 'Jon Snow',
    house: 'Stark',
    parents: [ 'Ned Stark' ]
  },
  { 
    name: 'Jaime Lannister',
    house: 'Lannister',
    parents: [
      'Tywin Lannister',
      'Joanna Lannister'
    ]
  },
  {
    name: 'Daenerys Targaryen',
    house: 'Targaryen',
    parents: [
      'Aerys II Targaryen',
      'Rhaella Targaryen'
    ]
  }
]

at(['[0].parents[0]', '[2].parents[1]'], characters)  // ['Ned Stark', 'Rhaella Targaryen']

// Using Destructuring Assignment
const [jonSnowFather, daenerysMother] = at(['[0].parents[0]', '[2].parents[1]'], characters)

console.log(jonSnowFather) // 'Ned Stark'
console.log(daenerysMother) // 'Rhaella Targaryen'

```

## pick
The `pick` method is very useful when you need to get just some of the attributes of a given object and, by using it, your code will become more understandable for those who read. To use it, you need to specify the attributes you want to retrieve within an array.

```javascript
import { pick } from 'lodash/fp'

const jonSnow = {
  firstName: 'Jon',
  lastName: 'Snow',
  isBastard: true,
  father: {
    firstName: 'Ned',
    lastName: 'Stark'
  },
  mother: 'Unknown',
  age: 14,
  wolf: 'Ghost'
}

pick(['firstName', 'father.firstName', 'wolf'], jonSnow) // { firstName: 'Jon', father: { firstName: 'Ned' }, wolf: 'Ghost' }
```

Notice that you can also get nested attributes from your object. When using 'father.firstName', the `pick` method will get the `father` object but containing only its `firstName` property.

## omit
The `omit` is like the "opposite" of pick.
Instead of getting the attributes specified, it will hide them from the result.

```javascript
import { omit} from 'lodash/fp'

const jonSnow = {
  firstName: 'Jon',
  lastName: 'Snow',
  isBastard: true,
  father: {
    firstName: 'Ned',
    lastName: 'Stark'
  },
  mother: 'Unknown',
  age: 14,
  wolf: 'Ghost'
}

omit(['firstName', 'father.firstName', 'wolf'], jonSnow) // { lastName: 'Snow', isBastard: true, father: { lastName: 'Stark' }, mother: 'Unknown', age: 14 }
```

The same rule for hiding nested attributes works here. Notice that, by using 'father.firstName' it means that the `firstName` will be omitted and only the `lastName` will be gotten from `father` attribute.

## orderBy
The `orderBy` method is useful to sort an array of objects considering a given property. You can sort value in both _ascending_ and _descending_ orders.

Take a look:

```javascript
import { orderBy } from 'lodash/fp'

const characters = [
  {
    name: 'Ned Stark',
    age: 52
  },
  {
    name: 'Daenerys Targaryen',
    age: 15
  },
  {
    name: 'Jon Snow',
    age: 17
  },
  {
    name: 'Arya Stark',
    age: 12
  }
]

orderBy('age', 'desc', characters)

/*

[
  {
    name: 'Ned Stark', 
    age: 52
  },
  {
    name: 'Jon Snow',
    age: 17
  }
  {
    name: 'Daenerys Targaryen',
    age: 15
  },
  {
    name: 'Arya Stark',
    age: 12
  }
]

*/
``` 

If you want to order items in _ascending_ order, all you need to do is replace the `'desc'` parameter by `'asc'`.

_`orderBy` is an evolved version of [`sortBy`](https://lodash.com/docs/4.17.15#sortBy)_

## intersectionBy
The `intersectionBy` method is useful to find items that belong to two different groups. You just need to pass the name of the property that will play as criteria for the intersection.

Check the examples:

```javascript
import { intersectionBy } from 'lodash/fp'

const goodGuys = [
  { name: 'Daenerys Targaryen' },
  { name: 'Jon Snow' },
  { name: 'Arya Stark' }
]

const badGuys = [
  { name: 'Cersei Lannister' },
  { name: 'Joffrey Lannister' },
  { name: 'Daenerys Targaryen' }
]

intersectionBy('name', goodGuys, badGuys) // [ { name: 'Daenerys Targaryen' } ]
```

_To deal with arrays of primitive values (numbers, strings) you may use the [`intersection`](https://lodash.com/docs/4.17.15#intersection) method_

---
These were some of the methods from Lodash Functional Programming Module that might be useful for you in a daily basis.
There a lot of other methods that can be used.

**Attention: some links in this article take you to the basic Lodash documentation. In order to use the FP version of the method, the parameters need to be ordered differently.**


I hope you liked it.
Please, comment and share!

_Cover image by: [Mika Baumeister](https://unsplash.com/@mbaumi)_