简体   繁体   中英

Finding multiple objects in an array and adding to count value for that object

I have been toying with the best way to go about doing this and have found some options but not one that preserves the format I am trying to keep for the array/object.

The overview is I have an array that gets random objects pushed into it and there can be duplicates of the same object, but I want to change it so there is only 1 of each object and instead, having a count property for each object.

An example of what I am working with and what I am aiming to have.

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 }
];

As a side note, I am wondering if it better to do this after the array is filled or if it is better to do this while pushing the objects into the array?

If items are continuously being added, you can maintain an "index" (by Name ) of objects you've already added to the array so that whenever a new object is added, you can update the count if it's already present or push it to the array if it's not:

 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); 

The benefit of this approach is that you don't have to recompute counts from scratch (which is an O(n) operation) every time you want to get the result array.

Assuming the value of each item is the same, you can do a simple forEach loop. For each element, check to see if the object exists in 'result'. If so, increment the count, otherwise add it to the result array.

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);

In this case, you don't want to use arr.map, since we're not updating the original array.

You could take a hash table and count same items.

 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; } 

You can loop through the array and maintain 1 temporary object with "Name" as a key, If same name is found increment "count" by 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); 

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM