I have a large dataset in the form:
data = [{ a: 12, b: 8 }, { a: 2, c: 4, d: 14 }, { c: 2, e: 4, f: 14 }]
What I want is an object with all keys (here a-f) and the sum of their values across the data set, like so:
{ a: 14, b: 8, c: 6, d: 14, e: 4, f: 14 }
I can get the desired result like this:
function sum(a, b) { return a + b };
function countTotal(n) {
let ndata = data.filter((i) => Object.keys(i).includes(n))
let cnt = Object.assign(ndata.map((i) => i[n])).reduce(sum);
return {[n]:cnt};
};
let names = 'abcdef'.split('')
let res = Array.from(names).map((n) => countTotal(n))
res = Object.assign({}, ...res);
My problem is that this takes quite long for the actual data set I have (which is quite big). Is there a way to do the same more efficiently?
Below is some code do create a large dummy data set approximating the real data set.
let dummy_names = [];
for (let i = 0; i < 2000; i++) {
dummy_names.push((Math.random() + 1).toString(36).slice(2,7));
};
dummy_names = [...new Set(dummy_names)];
names = new Set();
function makeResponses() {
let responses = {};
let idx = 0;
for (let j = 0; j <= Math.floor(Math.random() * 7); j++) {
idx = Math.floor(Math.random()*dummy_names.length);
inam = dummy_names[idx];
names.add(inam);
responses[inam] = Math.floor(Math.random()*20);
};
return responses;
};
let data = [];
for (let i = 0; i < 20000; i++) {
data.push(makeResponses());
};