Heim  >  Fragen und Antworten  >  Hauptteil

Gibt es eine schnellere Möglichkeit, Schlüsselwerte in einem großen Array von Objekten zusammenzufassen?

Ich habe einen großen Datensatz im Format:

data = [{ a: 12, b: 8 }, { a: 2, c: 4, d: 14 }, { c: 2, e: 4, f: 14 }]

Was ich möchte, ist ein Objekt, das die Summe aller Schlüssel (hier a-f) und deren Werte im Datensatz enthält, etwa so:

{ a: 14, b: 8, c: 6, d: 14, e: 4, f: 14 }

So kann ich das gewünschte Ergebnis erzielen:

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

Mein Problem ist, dass dies für den tatsächlichen Datensatz, den ich habe (der ziemlich groß ist), sehr lange dauert. Gibt es eine Möglichkeit, dies effizienter zu machen?

Einige der folgenden Codes erstellen einen großen Dummy-Datensatz, der dem tatsächlichen Datensatz nahe kommt.

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 Tage vor390

Antworte allen(1)Ich werde antworten

  • 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);

    Antwort
    0
  • StornierenAntwort