#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
функция мне нравится больше, чем моя