简体   繁体   English

如何将具有相同属性的对象合并到一个数组中?

[英]How to merge objects with the same properties into a single Array?

I'm reciving the next data 我正在收到下一个数据

    [
      { id: "1", name: "test1", rName: "the1" },
      { id: "1", name: "test1", rName: "the2" },
      { id: "1", name: "test1", rName: "the3" },
      { id: "2", name: "test2", rName: "the1" },
      { id: "2", name: "test2", rName: "the2" },
      { id: "3", name: "test3", rName: "the1" }
    ]

I want to merge it by the id and push the rName's into an array to have this structure 我想通过id合并它并将rName推入一个数组以获得这个结构

    [
      { id: "1", name: "test1", rName: ["the1", "the2","the3"] },
      { id: "2", name: "test2", rName: ["the1", "the2"] },
      { id: "3", name: "test3", rName: ["the1"] }
    ]

I thought doing it with reduce but didn't succeed, if anyone can point me to the right direction it will be greatly appreciated. 我认为这样做会减少,但没有成功,如果有人能指出我正确的方向,将不胜感激。

This is a pretty simple case of data reformatting. 这是一个非常简单的数据重新格式化案例。 Code is below. 代码如下。

 var data = [ { id: "1", name: "test1", rName: "the1" }, { id: "1", name: "test1", rName: "the2" }, { id: "1", name: "test1", rName: "the3" }, { id: "2", name: "test2", rName: "the1" }, { id: "2", name: "test2", rName: "the2" }, { id: "3", name: "test3", rName: "the1" } ]; var reduced = Object.values(data.reduce(function(accumulator, element) { if (!accumulator[element.id]) { accumulator[element.id] = { id: element.id, name: element.name, rName: [] }; } accumulator[element.id].rName.push(element.rName); return accumulator; }, {})); console.log(reduced); 

The accumulator checks if the key by element.id exists in the accumulator. 累加器检查按element.id中的键是否存在于累加器中。 If it does not, it creates it. 如果没有,则创建它。 It then pushes the new rName on the existing stack. 然后它在现有堆栈上推送新的rName Object.values() is then used to make the conversion back to an array. 然后使用Object.values()将转换返回到数组。

You can use reduce and find like this: 您可以使用reducefind如下:

In the reduce accumulator , check if there is already an item with same id as the current item being iterated. 在reduce accumulator ,检查是否已存在与正在迭代的当前项具有相同id的项。 If yes, push the current item's rName to the rName array. 如果是,请将当前项的rName推送到rName数组。 Else, push a new item to the accumulator 否则,将新项目推送到accumulator

 var data = [ { id: "1", name: "test1", rName: "the1" }, { id: "1", name: "test1", rName: "the2" }, { id: "1", name: "test1", rName: "the3" }, { id: "2", name: "test2", rName: "the1" }, { id: "2", name: "test2", rName: "the2" }, { id: "3", name: "test3", rName: "the1" } ]; const newArray = data.reduce((acc, {id,name,rName}) => { const existing = acc.find(a => a.id == id); if (existing) existing["rName"].push(rName); else acc.push({id,name,rName: [rName]}) return acc }, []); console.log(newArray) 

This is a one line, code-golf answer. 这是一个代码高尔夫的答案。 (Got the idea from @Sébastien's answer): (从@Sébastien的回答中得到了想法):

 var data = [ { id: "1", name: "test1", rName: "the1" }, { id: "1", name: "test2", rName: "the2" }, { id: "1", name: "test2", rName: "the3" }, { id: "2", name: "test2", rName: "the1" }, { id: "2", name: "test1", rName: "the2" }, { id: "3", name: "test3", rName: "the1" } ] const anotherArray = Object.values(data.reduce((acc, {id,name,rName}) => ((acc[id] = acc[id] || {id,name,rName:[]})["rName"].push(rName), acc), {})); console.log(anotherArray) 

Pure ES6 纯ES6

let result = obj.reduce((acc, item) => {
  let found = acc.find(i => i.id === item.id);
  found ? (found.rName = [...found.rName, item.rName]) : (acc = [...acc, { ...item, rName: [item.rName] }]);
  return acc;
}, []);

If each id can determine a unique name , this will work: 如果每个id都可以确定唯一的name ,那么这将起作用:

let data = [
  { id: "1", name: "test1", rName: "the1" },
  { id: "1", name: "test1", rName: "the2" },
  { id: "1", name: "test1", rName: "the3" },
  { id: "2", name: "test2", rName: "the1" },
  { id: "2", name: "test2", rName: "the2" },
  { id: "3", name: "test3", rName: "the1" }
];

let result = [];

for (let item of data) 
{
    const index = result.findIndex(i => i.id === item.id);
    if (index < 0) {
        result.push({ id: item.id, name: item.name, rName: [item.rName] });
    }
    else {
        result[index].rName.push(item.rName);
    }
}

Please note this will not work when following data should accept: 请注意,当以下数据接受时,这将不起作用:

[
  { id: "1", name: "test1", rName: "the1" },
  { id: "1", name: "test2", rName: "the2" },
  { id: "1", name: "test2", rName: "the3" },
  { id: "2", name: "test2", rName: "the1" },
  { id: "2", name: "test1", rName: "the2" },
  { id: "3", name: "test3", rName: "the1" }
]

If you adhere to use method 'reduce', you can do like this: 如果你坚持使用'reduce'方法,你可以这样做:

var arr = [
        { id: "1", name: "test1", rName: "the1" },
        { id: "1", name: "test1", rName: "the2" },
        { id: "1", name: "test1", rName: "the3" },
        { id: "2", name: "test2", rName: "the1" },
        { id: "2", name: "test2", rName: "the2" },
        { id: "3", name: "test3", rName: "the1" }
    ]
    var arr1 = arr.reduce(function (a1, a2) {
        if (a1 instanceof Array) {
            let lastItem = a1[a1.length - 1]
            if (lastItem.id == a2.id) {
                lastItem.rName.push(a2.rName)
            } else {
                a1.push({ ...a2, rName: [a2.rName] })
            }
            return a1
        } else {
            let result = []
            if (a1.id == a2.id) {
                result.push({ ...a1, rName: [a1.rName, a2.rName] })
            } else {
                result.push({ ...a1, rName: [a1, rName] })
                result.push({ ...a2, rName: [a2, rName] })
            }
            return result

        }

    })
    console.log(JSON.stringify(arr1))

But I think you should do like this, for the code is more clear: 但我认为你应该这样做,因为代码更清晰:

var arr = [
    { id: "1", name: "test1", rName: "the1" },
    { id: "1", name: "test1", rName: "the2" },
    { id: "1", name: "test1", rName: "the3" },
    { id: "2", name: "test2", rName: "the1" },
    { id: "2", name: "test2", rName: "the2" },
    { id: "3", name: "test3", rName: "the1" }
]
var map = new Map()
arr.forEach(function(item){
    if(map.has(item.id)){
        map.get(item.id).rName.push(item.rName)
    }else{
        map.set(item.id, {...item, rName: [item.rName]})
    }
})
var arr1 = Array.from(map.values())
console.log(JSON.stringify(arr1))

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

相关问题 如何将具有相同属性的对象合并到一个数组中? - How to merge objects with the same properties into an Array? 如何将对象列表数组合并为单个数组 - How to Merge array of objects list into single array 将具有相同属性的两个对象的方法合并到每个属性的数组中 - Merge methods of two objects with same properties into array for each property 对象数组(JavaScript)合并并使用相同的键添加属性 - Array of Objects (JavaScript) merge and add properties with same key 如果 javascript 中的 id 相同,如何合并数组中所有属性的两个对象? - How to merge two objects of all properties in an array if it has same id in javascript? 如何使用lodash合并/连接对象数组中相同对象属性的值? - How to merge/concatenate values of same object properties in an array of objects using lodash? 在单个对象数组中合并对象 - Merge objects in a single objects array 使用相同属性值的数组将多个对象合并为单个对象 - Merge multiple objects into single object with making array of same property values 合并对象数组的相同属性并在该 object 数组中创建 object 数组以获得不同的属性 - merge same properties of array of objects and create array of object within that array of object for different properties 将对象数组合并为单个数组 - Merge array of Objects into Single Array
 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM