我有一个大型数据集,格式为:
data = [{ a: 12, b: 8 }, { a: 2, c: 4, d: 14 }, { c: 2, e: 4, f: 14 }]
我想要的是一个包含所有键(此处为 a-f)及其在数据集中的值之和的对象,如下所示:
{ a: 14, b: 8, c: 6, d: 14, e: 4, f: 14 }
我可以得到这样的期望结果:
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);
我的问题是,对于我拥有的实际数据集(相当大)来说,这需要很长时间。有没有办法更有效地做到这一点?
下面的一些代码确实创建了一个近似真实数据集的大型虚拟数据集。
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()); };
我将使用辅助对象来跟踪总和并循环遍历数组中的对象。
最重要的是只查看每个值一次,以保持较低的复杂性(以 O 表示法表示)。迭代的方式有很多种,不知道是for循环还是
.forEach
更快。这是一个粗略的解决方案: