合并具有1个相同属性名称的对象数组

时间:2017-12-29 04:18:14

标签: javascript

我试图将每个对象合并为一个重复的名称'财产,合并,我的意思是添加他们的价值'财产在一起并删除重复的。

出于某种原因,我的代码没有给出预期的结果:



    array = [ 
        { name: 'f', value: '10' },
        { name: '5', value: '10' },
        { name: 'f', value: '10' },
        { name: '5', value: '10' },
        { name: 'f', value: '10' },
        { name: '5', value: '10' },
    ]

    for (let i = 0; i < array.length; i++) {
        for (let y = 0; y < array.length; y++) {

            if (array[y].name == array[i].name) {

                array[i].value = parseInt(array[i].value) + parseInt(array[y].value)

                array.splice(y,1)
                
            }
        }
    }
    
    console.log(array)
    // gives result [ { name: '5', value: 30 }, { name: 'f', value: '10' } ]
    // expected results [ { name: '5', value: 30 }, { name: 'f', value: '30' } ]
&#13;
&#13;
&#13;

4 个答案:

答案 0 :(得分:3)

使用reducemap的组合来执行此操作:

let array = [
      { name: 'f', value: '10' },
      { name: '5', value: '10' },
      { name: 'f', value: '10' },
      { name: '5', value: '10' },
      { name: 'f', value: '10' },
      { name: '5', value: '10' },
    ];
    
    let resultObj = array.reduce((result, item) => {
      result[item.name] = (result[item.name] || 0) + (Number(item.value) || 0);
      return result;
    }, {});
    
    let resultArray = Object.getOwnPropertyNames(resultObj).map(name => {
      return {name, value: resultObj[name]}
    })
    
    console.log(resultArray)

答案 1 :(得分:1)

看起来像Array.prototype.reduceArray.prototype.map的作业。

首先要做的是为累积值生成Map个名称。

然后,您可以将其转换为具有名称和总计的对象数组。

&#13;
&#13;
const array = [ 
    { name: 'f', value: '10' },
    { name: '5', value: '10' },
    { name: 'f', value: '10' },
    { name: '5', value: '10' },
    { name: 'f', value: '10' },
    { name: '5', value: '10' }
]

const totals = array.reduce((map, item) => map.set(
    item.name, parseInt(item.value) + (map.get(item.name) || 0)
), new Map())

const merged = Array.from(totals)
    .map(([name, value]) => ({ name, value }))

console.info('Merged', merged)
&#13;
&#13;
&#13;

注意: Map迭代按插入顺序排列,因此&#34; f&#34;将是第一个,然后是&#34; 5&#34;。如果您需要更改订单,则应使用Array.prototype.sort

答案 2 :(得分:0)

这里的问题是你正在迭代和更新同一个数组,因为当你删除索引时,数组索引会移动而你会错过很少的元素。请尝试以下代码:

array = [ 
    { name: 'f', value: '10' },
    { name: '5', value: '10' },
    { name: 'f', value: '10' },
    { name: '5', value: '10' },
    { name: 'f', value: '10' },
    { name: '5', value: '10' },

]
newArray = [];
for (let i = 0; i < array.length; i++) {
    var found=false;
   for(let j= 0;j<newArray.length;j++)   {
        if(newArray[j].name == array[i].name)    {
            newArray[j].value = parseInt(array[i].value)+ parseInt(newArray[j].value);
            found = true;
            break;
        }
   }
   if(!found)    {
    newArray.push(array[i]);
    }
}

console.log(newArray);

答案 3 :(得分:0)

这种情况正在发生,因为当您更新y处的元素并删除i处的元素时,您无法确保iy不同。所以你有一种情况,你正在修改一个项目,然后立即删除它。

有更好的方法可以做到这一点,但这里有一个简单的方法来修复你已经拥有的东西:

let array = [ 
    { name: 'f', value: '10' },
    { name: '5', value: '10' },
    { name: 'f', value: '10' },
    { name: '5', value: '10' },
    { name: 'f', value: '10' },
    { name: '5', value: '10' },
]

for (let i = 0; i < array.length; i++) {
    for (let y = 0; y < array.length; y++) {
        //  v-- ensure y and i are not the same
        if (y !== i && array[y].name === array[i].name) {
             array[i].value = parseInt(array[i].value) + parseInt(array[y].value)
             array.splice(y,1)
        }
    }
}
   
console.log(array)