Reputation: 923
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
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
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
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
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