Reputation: 449
I'm looking for an effective way to count the occurrence of elements. I read the data in a loop, and in every step I want to increase the right object element in the result array, or create a new one, if it isn't available yet.
I have to work with a lot of data, so I need a quick solution. Here is a working version:
var hugeDataObject = [
{id: '1234', dark: true},
{id: '5678', dark: true},
{id: '91011', dark: true},
{id: '91011', dark: false}
];
var ids = [];
var darks = [];
var allIds = [];
var allDarks = [];
hugeDataObject.forEach(function(attrs) {
var index = allIds.indexOf(attrs.id);
if(index >= 0) ids[index].amount += 1;
else {
ids.push({type: attrs.id, amount: 1});
allIds.push(attrs.id);
}
var index = allDarks.indexOf(attrs.dark);
if(index >= 0) darks[index].amount += 1;
else {
darks.push({type: attrs.dark, amount: 1});
allDarks.push(attrs.dark);
}
});
Fiddle But I have more types, what I need to count, so there is too much variable.
The result:
ids = [
{type: '1234', amount: 1},
{type: '5678', amount: 1},
{type: '91011', amount: 2}
]
darks = [
{type: true, amount: 3},
{type: false, amount: 1}
]
(If you use loDash, it's ok)
Thanks in advance!
Upvotes: 0
Views: 75
Reputation: 449
It's not too simple, but I got it.
var getObjectBy = function(base, id, array) {
for (var i = 0, len = array.length; i < len; i++) {
if (array[i][base] === id) return array[i];
}
return null;
};
var hugeDataObject = [
{id: '1234', dark: true},
{id: '5678', dark: true},
{id: '91011', dark: true},
{id: '91011', dark: false}
];
var ids = [];
var darks = [];
hugeDataObject.forEach(function(attrs) {
var index = getObjectBy('type', attrs.id, ids);
if (index === null) ids.push({type: attrs.id, amount: 1});
else index.amount += 1;
var index = getObjectBy('type', attrs.dark, darks);
if (index === null) darks.push({type: attrs.dark, amount: 1});
else index.amount += 1;
});
Perhaps it isn't too pretty, but I think effective. If you know a better way, write it, and I will accept that!
Thanks your answers guys!
Upvotes: -1
Reputation: 26291
var counter = {};
hugeDataObject.forEach(function(attrs) {
if (counter[attrs.id]) {
counter[attrs.id]++;
}
else {
counter[attrs.id] = 1;
}
});
Or if you need array:
var counts = [];
var indexMap = {};
var i = 0;
indexMap[0] = -1;
hugeDataObject.forEach(function(attrs) {
var index = indexMap[attrs.id];
if (index == undefined) {
indexMap[attrs.id] = i;
counts[i] = { id: attrs.id, amount: 1 };
i++;
}
else {
var existingCounter = counts[index];
existingCounter.amount++;
}
});
Upvotes: 1
Reputation: 1685
If I understand your point, then you try use this:
var ids = [];
var allIds = [];
hugeDataObject.forEach(function(attrs) {
var index = allIds.indexOf(attrs.id);
if(index >= 0){
ids[index].amount = ids[index].amount + 1;
} else {
ids.push({type: attrs.id, amount: 1});
allIds.push(attrs.id);
// Here first should check is this type available,
// after create it or increase the amount
}
});
console.log(ids);
Upvotes: 0
Reputation: 80011
How about a simpler structure to store:
var objects = {};
objects['id1234'] = 384;
objects['id5678'] = 955;
objects['id91011'] = 1510;
/* increment */
objects['id1234']++;
Upvotes: 1