Как свести два зависимых массива в объект в JavaScript?

#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)