首页  >  问答  >  正文

是否有一种更快的方法来汇总大型对象数组中的键值?

我有一个大型数据集,格式为:

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());
    };

P粉191323236P粉191323236245 天前389

全部回复(1)我来回复

  • P粉976488015

    P粉9764880152024-02-18 15:15:02

    我将使用辅助对象来跟踪总和并循环遍历数组中的对象。

    最重要的是只查看每个值一次,以保持较低的复杂性(以 O 表示法表示)。迭代的方式有很多种,不知道是for循环还是.forEach更快。

    这是一个粗略的解决方案:

        const data = [{a: 12, b: 8}, {a: 2, c: 4, d: 14}, {c: 2, e: 4, f: 14}];
        const sums = {};
        data.forEach(object => {
            Object.entries(object).forEach(([key, value]) => {
                if (sums.hasOwnProperty(key)) {
                    sums[key] += value;
                } else {
                    sums[key] = value;
                }
            });
        });
        console.log(sums);

    回复
    0
  • 取消回复