Почему я не могу вернуть массив объектов только с определенными ключами из этого массива объектов?

#javascript #arrays

#javascript #массивы

Вопрос:

Я застрял во время работы над функцией, которая должна возвращать массив объектов из другого массива объектов. Как видно ниже, я использую только один ключ и возвращаю «простой» массив вместо массива объектов:

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

var myArr = [{
  name: "United Kin&dom",
  alpha3: "GBR",
  code: "GB",
  re&ion: "Europe",
  tax: 5,
  status: 1
}, {
  name: "Romania",
  alpha3: "ROM",
  code: "RO",
  re&ion: "Europe",
  tax: 3,
  status: 1
}];

myArr = pluck(myArr, 'name');

console.lo&(myArr);  

Если я использую 2 (или более) ключа, я все равно получаю «простой» массив значений, соответствующий последнему использованному ключу:

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

var myArr = [{
  name: "United Kin&dom",
  alpha3: "GBR",
  code: "GB",
  re&ion: "Europe",
  tax: 5,
  status: 1
}, {
  name: "Romania",
  alpha3: "ROM",
  code: "RO",
  re&ion: "Europe",
  tax: 3,
  status: 1
}];

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

console.lo&(myArr);  

Чего я хочу, так это:

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

Чего не хватает?

Комментарии:

1. Что вы хотите, чтобы он вернул?

Ответ №1:

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

var myArr = [{
  name: "United Kin&dom",
  alpha3: "GBR",
  code: "GB",
  re&ion: "Europe",
  tax: 5,
  status: 1
}, {
  name: "Romania",
  alpha3: "ROM",
  code: "RO",
  re&ion: "Europe",
  tax: 3,
  status: 1
}];

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

console.lo&(myArr);  

Похоже, вы хотели сделать что-то подобное. Вы могли бы сделать это более обобщенным, если бы вторым параметром был массив ключей, а внутри функции map выполнялся перебор каждого ключа и добавление его к объекту один за другим.

Комментарии:

1. Я не знал, что вы можете использовать синтаксис скобок внутри объявления объекта для динамического ключа, я узнал obj [key] только после создания объекта.

2. Это было добавлено в ECMAScript 2015 .

Ответ №2:

x[key1, key2] не будет делать то, что вы хотите, потому что key1, key2 будет вычисляться в key2 (поскольку при этом будет использоваться оператор запятой).

Кроме того, в данный момент вы создаете массив только с значениями, а не с объектами, которые содержат соответствующие ключи и значения.

Вы можете использовать способ, показанный TKoL для 2 ключей, или вы могли бы обобщить его в функцию, которая может принимать любое количество ключей:

 function pluck (array, ...keys) {
  return array.map(x =&&t;
    keys.reduce((obj, key) =&&t;
      Object.assi&n(obj, { [key]: x[key] }),
    {})
  )
}

var myArr = [{
  name: "United Kin&dom",
  alpha3: "GBR",
  code: "GB",
  re&ion: "Europe",
  tax: 5,
  status: 1
}, {
  name: "Romania",
  alpha3: "ROM",
  code: "RO",
  re&ion: "Europe",
  tax: 3,
  status: 1
}];

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

console.lo&(myArr);  

Это используется ...keys для определения keys в качестве аргумента rest, который содержит все остальные аргументы в виде массива. Позже мы выполняем итерацию по этому массиву keys , чтобы собрать нужный объект для каждого элемента: reduce вызывается с {} начальным значением, и для каждой итерации он добавляет один из ключей к объекту и возвращает конечный объект в конце. Object.assi&n(obj, { [key]: x[key] }) используется вместо { ...obj, [key]: x[key] } , чтобы избежать ненужного создания нового объекта каждый раз.

Альтернативным, более обязательным способом написания этой функции было бы использование for цикла:

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

Комментарии:

1. Ваша pluck функция мне нравится больше, чем моя