#javascript #arrays #reduce
#javascript #массивы #уменьшить
Вопрос:
В результате SQL-запроса у меня есть два JavaScript-массива строк (каждый массив представляет собой один столбец в результате), которые могут содержать дубликаты, такие как:
arrOne = ["key_1", "key_1", "key_2", "key_3", "key_1", "key_1"]
arrTwo = ["val_1", "val_1", "val_3", "val_3", "val_2", "val_3"]
и мне нужно свести их в объект типа:
newObj = {
key_1: ["val_1", "val_2", "val_3"],
key_2: ["val_3"],
key_3: ["val_3"]
}
Итак, по сути, для каждой пары ключ-значение значение должно быть сокращенным списком уникальных значений из arrTwo.
Я пытался:
let newObj = arrOne.reduce((o, k, i) => ({...o, [k]: arrTwo[i]}), {})
что дает мне:
{ key_1: 'val_3', key_2: 'val_3', key_3: 'val_3' }
но мне нужно, чтобы в двух [i] частях был сокращенный список значений вместо последнего значения для каждого ключа.
Это может быть элегантное однострочное решение, но я новичок в JavaScript и не могу найти правильное решение (я думаю, что цикл здесь не нужен).
Ответ №1:
Вы могли бы взять Set
и собрать все значения.
var arrOne = ["key_1", "key_1", "key_2", "key_3", "key_1", "key_1"],
arrTwo = ["val_1", "val_1", "val_3", "val_3", "val_2", "val_3"],
newObj = arrOne.reduce(
(o, k, i) => ({ ...o, [k]: [...new Set([...(o[k] || []), arrTwo[i]])] }),
{}
);
console.log(newObj);
Комментарии:
1. Спасибо! Это именно то, что я искал 🙂
Ответ №2:
const arrOne = ["key_1", "key_1", "key_2", "key_3", "key_1", "key_1"];
const arrTwo = ["val_1", "val_1", "val_3", "val_3", "val_2", "val_3"];
console.log(
arrTwo.reduce((a, c, i) => {
if (a[arrOne[i]].indexOf(c) == -1) a[arrOne[i]].push(c);
return a;
}, arrOne.reduce((a, c) => {
a[c] = []; return a;
}, {})));
Ответ №3:
Используйте reduce для одного из первого массива и используйте index для доступа к свойству из второго массива
var arrOne = ["key_1", "key_1", "key_2", "key_3", "key_1", "key_1"]
var arrTwo = ["val_1", "val_1", "val_3", "val_3", "val_2", "val_3"]
let newObj = arrOne.reduce(function(acc, curr, index) {
// check if the object has such key and if it dont contain the corresponding value
if (acc[curr] amp;amp; acc[curr].indexOf(arrTwo[index]) === -1) {
acc[curr].push(arrTwo[index])
} else {
acc[curr] = [];
acc[curr].push(arrTwo[index])
}
return acc;
}, {});
console.log(newObj)