1

I am creating an array of objects. The array can have multiple same objects, so the final result would be something like:

MyArray = [obj1, obj1, obj2]

I want to count how many obj1 are in the array without declaring new variables since I want to use this method to store and count hundreds of different objects.

This is for an Angular web app to manage orders.

I was thinking of storing these objects as:

MyArray = [{obj1: 2}, {obj2: 1}]

but I can't figure out how to do it, nor how to increase the value when another obj is added.

Thanks in advance.

Gabriele Magno
  • 196
  • 1
  • 13
  • 3
    What's the condition of equality? Two "same" object = Same reference OR Same value? – FZs Jan 05 '19 at 17:06

4 Answers4

2

You could take a Map, where you could take the objects as keys and count the occurences.

var o1 = { a: 1 },
    o2 = { a: 1 },
    o3 = { a: 1 },
    array = [o1, o2, o1, o3, o1, o2],
    count = array.reduce((m, o) => m.set(o, (m.get(o) || 0) + 1), new Map);
    
console.log(Array.from(count));
.as-console-wrapper { max-height: 100% !important; top: 0; }
Nina Scholz
  • 376,160
  • 25
  • 347
  • 392
0

The shortest way to achieve this is to use a set followed by a filter.

Working example :

const data = [5, 5, 5, 4, 4, 8, 8, 8, 8, 8, 9]

const result = [...new Set(data)].map(value => ({
    value,
    amount: data.filter(field => field === value).length
}))

console.log(result)

And using the formatting you want for your output :

const data = [5, 5, 5, 4, 4, 8, 8, 8, 8, 8, 9]

const result = [...new Set(data)].map(value => ({
    [value]: data.filter(field => field === value).length
}))

console.log(result)
Treycos
  • 7,373
  • 3
  • 24
  • 47
0

var array=['a1','a1','b1','c1','c1']
var resultCount={}
array.forEach(ele=>{ resultCount[ele] = (resultCount[ele]||0) + 1;});
console.log(resultCount)
Biswadev
  • 1,456
  • 11
  • 24
-1

My first suggestion would be to try and use a library for JavaScript that includes MultiSet functionality (like in Java, for instance). This question could lead you to something that might work.

If you don't want to pull in another dependency, then you could define your own class that stores a Map property which uses the objects you want to store as keys and holds the count of the number of said objects as values (more on JavaScript Maps).

You could do this by providing a method, say, myMultiSet.add(obj), which will add the new element to the set if the obj is not already in the Map and set it's count value to 1. If the obj is already in the Map, then simply increment the value by 1.

Update

Here is a sample implementation:

class MultiSet {
  constructor() {
    this.items = new Map();
  }
  
  add(obj) {
    if (this.items.has(obj)) {
      console.log(`${obj} is already in items. Incrementing.`);
      this.items.set(obj, this.items.get(obj) + 1);
    } else {
      console.log(`${obj} is new to items. Adding.`);
      this.items.set(obj, 1);
    }
  }
  
  getCount(obj) {
    return this.items.get(obj);
  }
};

let obj1 = { blah: 1, blah2: 2 };

let myMultiSet = new MultiSet();

myMultiSet.add(obj1);
myMultiSet.add(1);
myMultiSet.add('tree');
myMultiSet.add(1);
myMultiSet.add(obj1);

console.log(`Number of obj1 in set: ${myMultiSet.getCount(obj1)}`);
console.log(`Number of 'tree' in set: ${myMultiSet.getCount('tree')}`);
console.log(`Number of 1 in set: ${myMultiSet.getCount(1)}`);
Tim Klein
  • 2,538
  • 15
  • 19