合并数组中具有相同ID的对象

时间:2019-11-04 11:22:43

标签: javascript ecmascript-6

我想我有一个死的简单问题,但仍然没有找到解决方案。我有一个看起来像这样的数组:

var originalArray = [{
  id: 1,
  elements: [1, 2]
},
{
  id: 1,
  elements: [3, 4]
},
{
  id: 5,
  elements: ['a', 'b']
},
{
  id: 5,
  elements: ['c', 'd']
}, {
  id: 27,
  elements: []
}]

我想将其修改为如下形式(通过id和join元素合并):

newArray = [{
  id: 1,
  elements: [1, 2, 3, 4]
}, {
  id: 5,
  elements: ['a', 'b', 'c', 'd']
}, {
  id: 27,
  elements: []
}]

我已经尝试过多次,但仍然没有找到一种优雅的方法。

7 个答案:

答案 0 :(得分:4)

您可以创建一个由ID键控的对象,并将具有相同ID的元素压入它们,然后转换回数组。这比遍历较大数组的每次迭代都更有效:

var originalArray = [{
  id: 1,
  elements: [1, 2]
},
{
  id: 1,
  elements: [3, 4]
},
{
  id: 5,
  elements: ['a', 'b']
},
{
  id: 5,
  elements: ['c', 'd']
}, {
  id: 27,
  elements: []
}];

const arrayHashmap = originalArray.reduce((obj, item) => {
  obj[item.id] ? obj[item.id].elements.push(...item.elements) : (obj[item.id] = { ...item });
  return obj;
}, {});

const mergedArray = Object.values(arrayHashmap);

console.log(mergedArray);

答案 1 :(得分:1)

尝试此代码:

var originalArray = [{
      id: 1,
      elements: [1, 2]
    },
    {
      id: 1,
      elements: [3, 4]
    },
    {
      id: 5,
      elements: ['a', 'b']
    },
    {
      id: 5,
      elements: ['c', 'd']
    }, {
      id: 27,
      elements: []
    }]
    var newArray = [];
    originalArray.forEach(item => {
       var newItem = {id: item.id, elements: []};
       originalArray.forEach(innerItem => {
          if(innerItem.id == item.id){
              newItem.elements = newItem.elements.concat(innerItem.elements);
          }
       });
      newArray.push(newItem);
    });
    console.log(newArray);

输出:

[{
  id: 1,
  elements: [1, 2, 3, 4]
}, {
  id: 5,
  elements: ['a', 'b', 'c', 'd']
}, {
  id: 27,
  elements: []
}]

答案 2 :(得分:1)

您可以使用reduce函数来做到这一点:

[{
  id: 1,
  elements: [1, 2]
},
{
  id: 1,
  elements: [3, 4]
},
{
  id: 5,
  elements: ['a', 'b']
},
{
  id: 5,
  elements: ['c', 'd']
}, {
  id: 27,
  elements: []
}].reduce((prev, cur) => {
    const index = prev.findIndex(v => v.id === cur.id);
    if (index === -1) {
       prev.push(cur);
    } else {
        prev[index].elements.push(...cur.elements);
    }
    return prev;
}, [])

答案 3 :(得分:1)

您可以使用Array.prototype.reduce()创建一个ID为属性的对象,并使用Object.values()获得结果:

const originalArray = [{id: 1, elements: [1, 2]}, {id: 1, elements: [3, 4]}, {id: 5, elements: ['a', 'b']}, {id: 5, elements: ['c', 'd']}, {id: 27, elements: []}]
const objIds = originalArray.reduce((a, { id, elements }) => {
  a[id] = a[id] || {id, elements: []}
  return {...a, ...{[id]: {id, elements: a[id].elements.concat(elements)}}}
}, {})
const result = Object.values(objIds)

console.log(result)
.as-console-wrapper { max-height: 100% !important; top: 0; }

答案 4 :(得分:1)

这将起作用,并且相当容易理解。 首先,我们检查id是否已在newArray中,并通过循环外的布尔值保留此ID的内存,稍后我们可以进行验证。 此后,如果id“空格”为空,我们将填充它,如果不是,则已经有一个ID。 因此,我们需要更新其元素。我们可以通过首先在新数组中获取与具有相同ID的初始数组中的重复对象相对应的对象来做到这一点。 之后,我们只需将重复中的每个元素推到新元素即可。


var originalArray = [{
  id: 1,
  elements: [1, 2]
},
{
  id: 1,
  elements: [3, 4]
},
{
  id: 5,
  elements: ['a', 'b']
},
{
  id: 5,
  elements: ['c', 'd']
}, {
  id: 27,
  elements: []
}]

var newArray = [];
for (obj of originalArray) {

    var empty = true;
    for (newobj of newArray) {
       if (obj.id == newobj.id) { empty = false; }
    }
    if (empty) {
        newArray.push({id: obj.id, elements: obj.elements});
    } else {
        for (newobj of newArray) {
           if (newobj.id == obj.id) {
               for (o of obj.elements) {
                 newobj.elements.push(o);
                }
           }
        }
    }
}
console.log(newArray);

答案 5 :(得分:1)

您可以使用reduce方法和Map来存储每个id的唯一值,然后使用扩展语法...创建一个数组。

var data = [{"id":1,"elements":[1,2]},{"id":1,"elements":[3,4]},{"id":5,"elements":["a","b"]},{"id":5,"elements":["c","d"]},{"id":27,"elements":[]}]

const result = data.reduce((r, {id, elements}) => {
  if(r.get(id)) r.get(id).elements.push(...elements);
  else r.set(id, {id, elements});
  return r;
}, new Map).values();

console.log([...result])

答案 6 :(得分:0)

您可以使用嵌套的for循环来做到这一点。

var originalArray = [{
  id: 1,
  elements: [1, 2]
},
{
  id: 1,
  elements: [3, 4]
},
{
  id: 5,
  elements: ['a', 'b']
},
{
  id: 5,
  elements: ['c', 'd']
}, {
  id: 27,
  elements: []
}]


for(let i=0;i<originalArray.length;i++){
  let key = originalArray[i].id;
  for(let j=i+1;j<originalArray.length;j++){
    if(originalArray[j].id == key){
      originalArray[i].elements  = [...originalArray[i].elements,...originalArray[j].elements];
      delete originalArray.splice(j,1);
    }

  }
}

console.log(originalArray);