1

I got stuck while working on a function that should return an array of objects from another array of objects. As can be seen below, I use only one key and return a "simple" array instead of an array of objects:

function pluck(array, key) {
  return array.map(x => x[key]);
}

var myArr = [{
  name: "United Kingdom",
  alpha3: "GBR",
  code: "GB",
  region: "Europe",
  tax: 5,
  status: 1
}, {
  name: "Romania",
  alpha3: "ROM",
  code: "RO",
  region: "Europe",
  tax: 3,
  status: 1
}];

myArr = pluck(myArr, 'name');

console.log(myArr);

If I use 2 (or more) keys, I still get a "simple" array of values corresponding to the last key used:

function pluck(array, key1, key2) {
  return array.map(x => x[key1, key2]);
}

var myArr = [{
  name: "United Kingdom",
  alpha3: "GBR",
  code: "GB",
  region: "Europe",
  tax: 5,
  status: 1
}, {
  name: "Romania",
  alpha3: "ROM",
  code: "RO",
  region: "Europe",
  tax: 3,
  status: 1
}];

myArr = pluck(myArr, 'name', 'code');

console.log(myArr);

What I want is:

var myArr = [
  {name: "United Kingdom", code: "GB"},
  {name: "Romania", code: "RO"}
]

What is missing?

1
  • What do you want it to return? Commented Aug 10, 2020 at 14:40

2 Answers 2

5

function pluck(array, key1, key2) {
  return array.map(x => ({
    [key1]: x[key1],
    [key2]: x[key2]
  }));
}

var myArr = [{
  name: "United Kingdom",
  alpha3: "GBR",
  code: "GB",
  region: "Europe",
  tax: 5,
  status: 1
}, {
  name: "Romania",
  alpha3: "ROM",
  code: "RO",
  region: "Europe",
  tax: 3,
  status: 1
}];

myArr = pluck(myArr, 'name', 'code');

console.log(myArr);

Seems like you meant to do something like that. You could make it more generalized by the second parameter being an array of keys, and inside the map function iterating over each key and adding it to the object one by one.

Sign up to request clarification or add additional context in comments.

2 Comments

I didn't know you could use the bracket syntax inside the object declaration for the dynamic key, I only knew obj[key] after creating the object.
4

x[key1, key2] won't do what you want, because key1, key2 will evaluate to key2 (since it would use the comma operator).

Plus, you are currently creating an array with just the values, not with objects that contain the relevant keys and values.

You can use the way TKoL showed for 2 keys, or you could generalize it into a function that can take any number of keys:

function pluck (array, ...keys) {
  return array.map(x =>
    keys.reduce((obj, key) =>
      Object.assign(obj, { [key]: x[key] }),
    {})
  )
}

var myArr = [{
  name: "United Kingdom",
  alpha3: "GBR",
  code: "GB",
  region: "Europe",
  tax: 5,
  status: 1
}, {
  name: "Romania",
  alpha3: "ROM",
  code: "RO",
  region: "Europe",
  tax: 3,
  status: 1
}];

myArr = pluck(myArr, 'name', 'code');

console.log(myArr);

This uses ...keys to define keys as a rest argument that contains all the remaining arguments as an array. Later we iterate over this array of keys to assemble the desired object for each element: reduce is called with {} as initial value, and for every iteration it adds one of the keys to the object and returns the final object at the end. Object.assign(obj, { [key]: x[key] }) is used instead of { ...obj, [key]: x[key] } to avoid unnecessary creation of a new object every time.

An alternative, more imperative way of writing this function would be using a for loop:

function pluck (array, ...keys) {
  return array.map(x => {
    const obj = {}
    for (const key of keys) {
      obj[key] = x[key]
    }
    return obj
  })
}

1 Comment

I like your pluck function more than mine

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.