Преобразуйте массив объектов в один объект - PullRequest
0 голосов
/ 07 сентября 2018

Я пытаюсь объединить массив объектов в один объект, который объединяет значения всех подобных свойств.

objArray = [{
  foo: ["f", "b"],
  bar: ["e"]
}, {
  foo: ["a", "c"],
  bar: ["a", "c"]
}, {
  foo: ["f", "b"],
  bar: ["z"]
}];
const newObj = {
  foo: [],
  bar: []
};
objArray.forEach((obj) => {
  newObj.foo.push(...obj.foo);
  newObj.bar.push(...obj.bar);
});
console.log(newObj);

Я получаю желаемый результат с кодом выше. Является ли использование цикла forEach, как описано выше, лучшим способом достижения того, что я намереваюсь сделать? В идеале я не хочу указывать свойства для слияния, я бы хотел, чтобы код автоматически объединял идентичные имена свойств.

Edit:

Мне нужно поддерживать IE11

Ответы [ 5 ]

0 голосов
/ 07 сентября 2018

Взяв ответ @charlietfl и отредактировав его для IE (используя Object.keys вместо Object.entries)

objArray = [{
  foo: ["f", "b"],
  bar: ["e"]
}, {
  foo: ["a", "c"],
  bar: ["a", "c"]
}, {
  foo: ["f", "b"],
  bar: ["z"]
}];

const res = objArray.reduce((acc, c) => {
  return Object.keys(c).reduce((a, k) => {
    let v = c[k];
    a[k] = (a[k] || []).concat(v);
    return a;
  }, acc);
}, {});

console.log(res)
0 голосов
/ 07 сентября 2018

Используя forEach как вы, но for in внутри.

var objArray = [{foo: ["f", "b"],bar: ["e"]},{foo: ["a", "c"],bar:["a", "c"]},{foo: ["f", "b"],bar: ["z"]}];

var newObj = {};

objArray.forEach(o => {
  for (p in o) {
    if (!(p in newObj)) {
      newObj[p] = [];
    }
    newObj[p] = [...newObj[p], ...o[p]];
  }
});

console.log(newObj);
0 голосов
/ 07 сентября 2018

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

var data = [{ foo: ["f", "b"], bar: ["e"] }, { foo: ["a", "c"], bar: ["a", "c"] }, { foo: ["f", "b"], bar: ["z"] }],
    merged = data.reduce((r, o) => 
        Object.entries(o).reduce((s, [k, v]) =>
            Object.assign(s, { [k]: (s[k] || []).concat(v) }), r), {});
        
console.log(merged);
.as-console-wrapper { max-height: 100% !important; top: 0; }
0 голосов
/ 07 сентября 2018

Для достижения ожидаемого результата используйте Object.keys и два цикла, используя forEach

  1. Первый цикл с forEach будет обрабатывать каждый объект
  2. Второй цикл с Object.keys будет обрабатывать ключи каждого объекта и выдвигать новый массив с ключами
  3. Используйте Object.hasOwnProperty для значения ключа в newObj с оригинальными свойствами объекта массива

objArray = [
  {
    foo: ["f", "b"],
    bar: ["e"],
    zoo: ["z"]
  },
  {
    foo: ["a", "c"],
    bar: ["a", "c"]
  },
  {
    foo: ["f", "b"],
    bar: ["z"]
  }
];
const newObj = {
  foo: [],
  bar: []
};
objArray.forEach(obj => {
  Object.keys(obj).forEach(v => {
    if (newObj.hasOwnProperty(v)) {
      newObj[v].push(obj[v]);
    }
  });
});
console.log(newObj);

кодовая ручка для справки - https://codepen.io/nagasai/pen/MqOpWm?editors=1010

0 голосов
/ 07 сентября 2018

Может использовать вложенный метод limit (), равный Object#entries(), для итерации свойств без необходимости жестко кодировать конкретные имена свойств в любом месте

objArray = [{
  foo: ["f", "b"],
  bar: ["e"]
}, {
  foo: ["a", "c"],
  bar: ["a", "c"]
}, {
  foo: ["f", "b"],
  bar: ["z"]
}];

const res= objArray.reduce((acc,c)=>{
   return Object.entries(c).reduce((a,[k,v])=>{
       a[k] = (a[k] || []).concat(v)
       return a
   },acc)
},{})

console.log(res)
...