1

I want a nice small one liner to use an array, for example ['postcode','town'], and then pluck just these properties from a larger object.

So this:

const fields = ['postcode','town'];
const obj = {
    name: 'test',
    postcode: 'SS2 5JJ',
    town: 'Somewhere',
    other: 'info'
}

Would become this:

const filtered = {
    postcode: 'SS2 5JJ',
    town: 'Somewhere',
}

I did find this however I have mis-understood it I believe:

const fields = ['postcode','town'];
Object.keys(fields).map(e => fields[e])

What is the best way to do this?

Martyn Ball
  • 4,679
  • 8
  • 56
  • 126

5 Answers5

2

You could use Array.reduce

const fields = ['postcode', 'town'];
const obj = {
  name: 'test',
  postcode: 'SS2 5JJ',
  town: 'Somewhere',
  other: 'info'
};

const filteredObj = fields.reduce((acc, cur) => Object.assign(acc, { [cur]: obj[cur] }), {});

console.log(filteredObj);
a.mola
  • 3,883
  • 7
  • 23
  • 2
    IMO creating a new object just to merge it into an existing object is wasteful. Why not just `(acc, cur) => (acc[cur] = obj[cur], acc)` ? – Felix Kling Oct 08 '21 at 12:02
  • Is there any benefit to using Object.assign instead of the spread ("...") syntax? – Emil Karlsson Oct 08 '21 at 12:30
  • 1
    @EmilKarlsson, I don't there isn't any benefit, I saw this question where they spoke about it more https://stackoverflow.com/q/32925460/15350139 – a.mola Oct 08 '21 at 12:57
1

Maybe:

let res = Object.fromEntries(Object.entries(obj).filter(e => fields.includes(e[0]))
Alberto Sinigaglia
  • 12,097
  • 2
  • 20
  • 48
1

You can map your array fields to [key, value] which will create an array of [key, value] pairs. Once you have this array, you can use Object.fromEntries() to build your object for each key-value pair:

const fields = ['postcode','town'];
const obj = { name: 'test', postcode: 'SS2 5JJ', town: 'Somewhere', other: 'info' };

const res = Object.fromEntries(fields.map(key => [key, obj[key]]));
console.log(res);
Nick Parsons
  • 45,728
  • 6
  • 46
  • 64
1

"Best" is of course a subjective concept. But I think that the reduce function is the cleanest way of doing it. That way there is no need to chain together different functions.

const filtered = fields.reduce((prev, key) => ({[key]: obj[key], ...prev}), {});
Emil Karlsson
  • 1,000
  • 1
  • 7
  • 16
  • 1
    It probably won't have any impact, but this will still create one object per field and throws it away (except the last one). Again, not necessarily an issue but something to be at least aware of. – Felix Kling Oct 08 '21 at 13:28
-2

const fields = ['postcode','town'];
const obj = {
    name: 'test',
    postcode: 'SS2 5JJ',
    town: 'Somewhere',
    other: 'info'
}
const newObj = {};
Object.keys(obj).forEach(key => {
  if (fields.includes(key)) {
    newObj[key] = obj[key];
  }
});
console.log(newObj);
Christian
  • 7,433
  • 4
  • 36
  • 61