Lodash's `pick()` Function

Apr 10, 2020

Given an object obj and an array of string paths, Lodash's pick() function returns a new object with just the keys paths from obj.

const obj = {
  name: 'Will Riker',
  rank: 'Commander',
  age: 29
};
const picked = _.pick(obj, ['name', 'rank']);

picked === obj; // false
picked.name; // 'Will Riker'
picked.rank; // 'Commander'
picked.age; // undefined

The pick() function also supports dotted paths and any other syntax that Lodash's get() function supports. For example, if name is a nested object with 2 properties, first and last, you can pick just name.last and omit name.first.

const obj = {
  name: {
    first: 'Will',
    last: 'Riker'
  },
  rank: 'Commander',
  age: 29
};
const picked = _.pick(obj, ['name.last', 'rank']);

picked === obj; // false
picked.name.first; // undefined
picked.name.last; // 'Riker'
picked.rank; // 'Commander'
picked.age; // undefined

pick() is permissive when it comes to missing properties. If you try to pick() a dotted property whose parent is undefined, Lodash will just ignore that path.

const obj = {
  name: 'Will Riker',
  rank: 'Commander',
  age: 29
};
// Lodash will ignore 'this.is.not.in.the.object', because
// that path isn't in the object.
const picked = _.pick(obj, ['name', 'this.is.not.in.the.object']);

picked === obj; // false
picked.name; // 'Will Riker'
picked.rank; // undefined
picked.age; // undefined

Several other frameworks have analogous pick() functions. For example, Mongoose schemas have a pick() function that creates a new schema a subset of the original schema's paths.

Vanilla JS Alternatives

There are a couple of different patterns you can use to approximate Lodash's pick() function in vanilla JavaScript. Our favorite is to use an IIFE as shown below:

const obj = {
  name: 'Will Riker',
  rank: 'Commander',
  age: 29
};

// Looks tricky, but the idea is that you're calling an anonymous arrow
// function that returns just the `name` and `rank` properties of the passed
// in object.
const picked = (({ name, rank }) => ({ name, rank }))(obj);
picked.name; // 'Will Riker'
picked.rank; // 'Commander'
picked.age; // undefined

Below is an easier to read, but less concise, way of doing the same thing:

const pickNameRank = ({ name, rank }) => ({ name, rank });
const picked = pickNameRank(obj);

This IIFE approach has a few downsides:

  1. You need to know the property names ahead of time. It would be tricky to extend this pattern to operate on an array of keys.
  2. No support for dotted keys. You can't do something like ({ 'name.first' }) => ....

Another approach we like is defining a function with a for loop that creates a new object as shown below. This approach is less concise, but more flexible.

function pick(obj, keys) {
  const ret = {};
  for (const key of keys) {
    ret[key] = obj[key];
  }
  return ret;
}

More Lodash Tutorials