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