我有一個大型資料集,格式為:
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
比較快。這是一個粗略的解決方案: