在数组中查找多个对象并为该对象添加计数值

时间:2018-11-14 21:04:50

标签: javascript arrays reactjs object array.prototype.map

我一直在尝试最好的方法,找到了一些选择,但是没有一个保留我试图为数组/对象保留的格式。

概述是我有一个将随机对象推入其中的数组,并且同一对象可以重复,但是我想更改它,因此每个对象只有1个,而每个对象都有一个count属性对象。

一个我正在工作的目标以及想要拥有的目标的例子。

arr = [
  { Name: Item1, Value: 20 },
  { Name: Item2, Value: 20 },
  { Name: Item1, Value: 20 }
];

result = [
  { Name: Item1, Value: 20, Count: 2 },
  { Name: Item2, Value: 20, Count: 1 }
];

作为旁注,我想知道在数组填充后执行此操作是否更好,还是在将对象推入数组时执行此操作是否更好?

4 个答案:

答案 0 :(得分:1)

如果连续添加项目,则可以维护已经添加到数组中的对象的“索引”(按Name),以便每当添加新对象时,如果它已经存在,或者如果不存在,则将其推送到数组:

var arr = [];
var index = {};

function addItem(o) {
  if (o.Name in index) {
    index[o.Name].Count += 1;
  } else {
    index[o.Name] = o;
    o.Count = 1;
    arr.push(o);
  }
}

addItem({
  Name: 'Item1',
  Value: 20
});
addItem({
  Name: 'Item2',
  Value: 20
});
addItem({
  Name: 'Item1',
  Value: 20
});

console.log(arr);

这种方法的好处是,您不必每次要获取result数组时都从头重新计算计数(这是一个 O(n)操作)。

答案 1 :(得分:1)

假设每个项目的值都相同,则可以执行一个简单的forEach循环。对于每个元素,检查对象是否存在于“结果”中。如果是这样,请增加计数,否则将其添加到结果数组中。

let result = [];

arr.forEach(item => {
  let resObj = result.find(resObj => resObj.Name === item.Name);
  resObj ? resObj.Count++ : result.push({'Name':item.Name, 'Value': item.Value, 'Count': 1});
});

console.log(result);

在这种情况下,由于我们不更新原始数组,因此您不想使用arr.map。

答案 2 :(得分:0)

您可以使用哈希表并计算相同的项目。

var array = [{ Name: 'Item1', Value: 20 }, { Name: 'Item2', Value: 20 }, { Name: 'Item1', Value: 20 }],
    result = Object.values(array.reduce((r, { Name, Value }) => {
        r[Name] = r[Name] || { Name, Value, Count: 0 };
        r[Name].Count++;
        return r;
    }, {}));

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

答案 3 :(得分:0)

您可以遍历数组并使用“名称”作为键维护1个临时对象,如果找到相同的名称,则将“计数”增加1

let array = [{ Name: 'Item1', Value: 20 }, { Name: 'Item2', Value: 20 }, { Name: 'Item1', Value: 20 }]
    
let tempResult = {}
for (let d of array) {
  tempResult[d.Name] = { 
     count: 1, 
     ...d, 
     ...(tempResult[d.Name] &&  { count: tempResult[d.Name].count + 1 }) 
  }
}

let result = Object.values(tempResult)
console.log(result);