Reputation: 147
var foo = [ { "a" : 15 }, { "b" : 25 }, { "a" : 15 }, {"c" : 13},{"c" : 13},{"c" : 13},{ "b" : 25 } ];
I would like to remove the duplicates and then sum up what's left. So the above would yield,
{ "a" : 15 },{ "b" : 25 }, {"c" : 13},
giving me 53
when I add what's left of the values.
I saw something similar here (Removing duplicate objects with Underscore for Javascript) but not really clear on how duplicates are removed.
I found the following solution but it did not work for me. http://bateru.com/news/2012/03/code-of-the-day-get-unique-objects-from-an-array-of-json-objects/
Any ideas? Thanks!
Upvotes: 2
Views: 341
Reputation: 215009
To address your update, here's code that keeps the first of duplicated elements:
var foo = [ { "a" : 15 }, { "b" : 25 }, { "a" : 15 }, {"c" : 13} ];
uniqs = uniqBy(foo, JSON.stringify)
values = uniqs.map(function(x) { for(var k in x) return x[k] })
sum = values.reduce(function(a, b) { return a + b })
uniqBy
is defined here: https://stackoverflow.com/a/9229821/989121
Let's try this:
> var foo = [ { "a" : 15 }, { "b" : 25 }, { "a" : 15 }, {"c" : 13} ];
undefined
> fkeys = foo.map(function(x) { return Object.keys(x)[0] })
["a", "b", "a", "c"]
> sum = foo.reduce(function(s, x) {
var key = Object.keys(x)[0];
if(fkeys.indexOf(key) == fkeys.lastIndexOf(key))
s += x[key];
return s;
}, 0)
38
The idea is to collect the keys first and then iterate over the array, ignoring keys that occur more than once (indexOf
!= lastIndexOf
).
If your arrays are huge (>5000 items), using a hash table instead of indexOf
might be more efficient:
> fkeys = {}
Object {}
> foo.forEach(function(x) {
var key = Object.keys(x)[0];
fkeys[key] = (Number(fkeys[key]) || 0) + 1;
})
undefined
> sum = foo.reduce(function(s, x) {
var key = Object.keys(x)[0];
if(fkeys[key] === 1)
s += x[key];
return s;
}, 0)
38
Upvotes: 4
Reputation: 1274
Why dont u try this for simple calculation part..This is only u want calculation by not considering duplicate object value..Its not suitable for pure object related manipulations
var array = [{ "a" : 15 }, { "b" : 25 }, { "a" : 15 }, {"c" : 13}];
var finVal=0;
var items = {};
var keys={};
for(var i=0;i<array.length;i++){
for(var key1 in array[i]){
if(items[key1]==undefined ){
items[key1] =array[i][key1];
var locVal = items[key1];
finVal = finVal+locVal;
} else {
//items[key1] =array[i][key1];
var locVal = items[key1];
finVal = finVal-items[key1];
}
}
}
console.log(finVal);
Upvotes: 0
Reputation: 2973
In the example you've posted underscore.js
library is used. look at the docs here link.
uniq _.uniq(array, [isSorted], [iterator])
Alias: unique Produces a duplicate-free version of the array, using === to test object equality. If you know in advance that the array is sorted, passing true for isSorted will run a much faster algorithm. If you want to compute unique items based on a transformation, pass an iterator function.
using it may save your time.
There you'll find example relying on clean javascript: Remove Duplicates from JavaScript Array
look at thg435 answer.
Upvotes: 0