Объединить объекты массива по имени ключа - PullRequest
0 голосов
/ 17 января 2020

Я хотел бы превратить этот вид массива:

let myArray = [
    { even: [2,4,6], odd: [1,3,5,7], decimals: [3.14, 12.8] },
    { even: [4,6,8], odd: [7,9,11,13], decimals: [111.1] },
    { even: [16,18], odd: [15,15,17] }
]

в:

myArray = [
    { even: [2,4,6,4,6,8,16,18] }, 
    { odd: [1,3,5,7,7,9,11,13,15,15,17] }, 
    { decimals: [3.14, 12.8, 111.1] },
]

Может быть, я должен использовать для этого «уменьшить», но я не знаком с этой функцией совсем. Если бы кто-нибудь мог показать мне хороший путь

Ответы [ 4 ]

2 голосов
/ 17 января 2020

Может быть, я могу дать вам более короткий и умный ответ:

myArray.reduce((acc, obj = {}) => ({
  even: [...acc.even, ...(obj.even || [])],
  odd: [...acc.odd, ...(obj.odd || [])],
  decimals: [...acc.decimals, ...(obj.decimals || [])],
}), { even: [], odd: [], decimals: []})

Функция Reduce очень мощная, и вы можете использовать ее со многими вариантами использования: когда вы хотите .filter() и .map() в одном массиве, вы можете оптимизировать его с помощью один .reduce() вызов.

Просмотр .reduce() в анимации: https://twitter.com/jacobmparis/status/1213887721799913479

Кстати: это решение использует объект в качестве вывода, а не массив

1 голос
/ 17 января 2020

Уменьшите массив до объекта-накопителя - преобразуйте каждый объект в исходном массиве в записи с помощью Object.entries(), итерируйте записи ([key, values]) с помощью Array.forEach() и сопоставляйте значения с предыдущими значениями ключа.

Снова преобразовать полученный объект в записи и отобразить в массив объектов.

const myArray = [
  { even: [2,4,6], odd: [1,3,5,7], decimals: [3.14, 12.8] },
  { even: [4,6,8], odd: [7,9,11,13], decimals: [111.1] },
  { even: [16,18], odd: [15,15,17] }
]

const result = Object.entries( // convert the accumulator to entries
    myArray.reduce((r, o) => {
      Object.entries(o) // convert object to entries
        .forEach(([k, v]) => r[k] = [...(r[k] || []), ...v]) // add the values to the respective key in the accumulator

      return r
    }, {})
  )
  .map(([k, v]) => ({ [k]: v })) // map to objects
  
console.log(result)
1 голос
/ 17 января 2020

Я думаю, этот формат результата будет лучше

myArray = {
    even: [2,4,6,4,6,8,16,18], 
    odd: [1,3,5,7,7,9,11,13,15,15,17], 
    decimals: [3.14, 12.8, 111.1],
}

Ниже код делает это.

const newObj = myArray.reduce((prev, item) => {
    for (key in item) {
        prev[key] = [...(prev[key] || []), ...item[key]]
    }

    return prev
}, {})
0 голосов
/ 17 января 2020

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

Попробуйте приведенный ниже фрагмент кода. Это может помочь вам.

function mergeArray(arr) {
  // Creating the JSON from the array with all the keys and merged data.
  const json = arr.reduce((acc, curr) => {
    Object.keys(curr).forEach(k => {
      if (Object.keys(acc).includes(k)) {
        acc[k].push(...curr[k]);
      } else {
        acc[k] = curr[k];
      }
    });
    
    return acc;
  }, {});
  
  // Converting the JSON to array with each key of JSON as separate element in array.
  return Object.keys(json).map(jsonKey => {
    return {
      [jsonKey]: json[jsonKey]
    };
  });
}

let myArray = [
    { even: [2,4,6], odd: [1,3,5,7], decimals: [3.14, 12.8] },
    { even: [4,6,8], odd: [7,9,11,13], decimals: [111.1] },
    { even: [16,18], odd: [15,15,17] }
];

console.log(mergeArray(myArray));
Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...