Steve
Steve

Reputation: 923

How can I count the occurrence of a value of an attribute in an array of anonymous objects

I'm hoping to find an efficient answer as as in the second answer (Rajesh Dhiman) in Jquery Count number of occurances in array

Javascript of JQuery are both acceptable.

Consider:

var items = new Array();
items.push({x: 1, y: "what"});
items.push({x: 3, y: "ever"});
items.push({x: 4, y: "can"});
items.push({x: 4, y: "happen"});
items.push({x: 1, y: "will"});
items.push({x: 4, y: "happen"});

Seeking results like (sorted or not doesn't matter):

res = {1:2, 3:1, 4:3}

All other related answers on here that I can find only consider counting simplistic arrays or not JS/JQ.

Upvotes: 2

Views: 96

Answers (4)

Nina Scholz
Nina Scholz

Reputation: 386550

No need for Array#reduce, an Array#forEach works well.

The result is an object. the reference does not change, so it is not necessary to use something which change the reference to a result.

If, for examle, a result is made of a countinuous addition, then the result would change, but here, with an object, it does not change. It is more some kind of laziness, to move an object through the reduce.

var items = [{ x: 1, y: "what" }, { x: 3, y: "ever" }, { x: 4, y: "can" }, { x: 4, y: "happen" }, { x: 1, y: "will" }, { x: 4, y: "happen" }],
    count = Object.create(null);

items.forEach(function(a) {
    count[a.x] = (count[a.x] || 0) + 1;
});

console.log(count);

As requested with an array of objects for the count. this proposal uses the this object hashing the included items in the result set.

var items = [{ x: 1, y: "what" }, { x: 3, y: "ever" }, { x: 4, y: "can" }, { x: 4, y: "happen" }, { x: 1, y: "will" }, { x: 4, y: "happen" }],
    result = [];

items.forEach(function(a) {
    if (!this[a.x]) {
        this[a.x] = { x: a.x, cnt: 0 };
        result.push(this[a.x]);
    }
    this[a.x].cnt++;
}, Object.create(null));

console.log(result);

With Array#reduce, a hash table as closure and an array.

var items = [{ x: 1, y: "what" }, { x: 3, y: "ever" }, { x: 4, y: "can" }, { x: 4, y: "happen" }, { x: 1, y: "will" }, { x: 4, y: "happen" }],
    result = items.reduce(function (hash) {
        return function(r, a) {
            if (!hash[a.x]) {
                hash[a.x] = { x: a.x, cnt: 0 };
                r.push(hash[a.x]);
            }
            hash[a.x].cnt++;
            return r;
        };
    }(Object.create(null)), []);

console.log(result);

Upvotes: 2

WLatif
WLatif

Reputation: 1378

Another approach would be to iterate over it and finding the occurrences. below is the code and the demo.

var items = new Array();
items.push({x: 1, y: "what"});
items.push({x: 3, y: "ever"});
items.push({x: 4, y: "can"});
items.push({x: 4, y: "happen"});
items.push({x: 1, y: "will"});
items.push({x: 4, y: "happen"});
var returnobj = {};

$.each(items, function(key, value) {
  if (returnobj.hasOwnProperty([value['x']])) {
    returnobj[value['x']] = returnobj[value['x']] + 1;
  } else {
    returnobj[value['x']] = 1;
  }
});
console.log(returnobj);
<script src="https://ajax.googleapis.com/ajax/libs/jquery/2.1.1/jquery.min.js"></script>

Upvotes: 0

kevin ternet
kevin ternet

Reputation: 4612

A quick and sorted solution :

var items = new Array();
items.push({x: 1, y: "what"});
items.push({x: 3, y: "ever"});
items.push({x: 4, y: "can"});
items.push({x: 4, y: "happen"});
items.push({x: 1, y: "will"});
items.push({x: 4, y: "happen"});
var res = items.map(x => ({x: x.x})).sort((a,b) => a.x - b.x).reduce((r,o) => {
    r[o.x] = (r[o.x] || 0) + 1;
    return r;
}, {});
console.log(res); //{ '1': 2, '3': 1, '4': 3 }

Upvotes: 0

Nenad Vracar
Nenad Vracar

Reputation: 122027

You can use reduce() and return object as result.

var items = new Array();
items.push({x: 1, y: "what"});
items.push({x: 3, y: "ever"});
items.push({x: 4, y: "can"});
items.push({x: 4, y: "happen"});
items.push({x: 1, y: "will"});
items.push({x: 4, y: "happen"});

var result = items.reduce(function(r, o) {
  r[o.x] = (r[o.x] || 0) + 1;
  return r;
}, {})

console.log(result)

Upvotes: 4

Related Questions