Lodash's `pick()` Function
Given an object obj
and an array of strings 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:
- 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.
- 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;
}