簡體   English   中英

如何對對象數組中的值進行分組和求和?

[英]How to group and sum values from array of objects?

我有一個對象數組( responses ),它可以包含任意數量的對象(即不確定的rounds數和questions ),以任何順序。 里面的對象將是相似的:

responses [
  {
    name: "personA"
    uniqueId: "abcd"
    roundNumber: 0
    questionNumber: 0
    score: 1
  },
  {
    name: "personA"
    uniqueId: "abcd"
    roundNumber: 0
    questionNumber: 1
    score: 1
  },
  {
    name: "personA"
    uniqueId: "abcd"
    roundNumber: 1
    questionNumber: 0
    score: 0
  },
    name: "personB"
    uniqueId: "efgh"
    roundNumber: 0
    questionNumber: 0
    score: 1
  },
  {
    name: "personB"
    uniqueId: "efgh"
    roundNumber: 0
    questionNumber: 1
    score: 0
  },
  {
    name: "personB"
    uniqueId: "efgh"
    roundNumber: 1
    questionNumber: 0
    score: 1
  }
]

我將如何根據對象的值對scores進行分組和求和? 更具體地說,我想獲取personA的所有對象(使用它們的nameuniqueId字段),然后通過roundNumber總結分數。 然后對每個玩家重復這個過程。

流程示例:

  • personA的得分求和為roundNumber: 0 ,然后保存。
  • personA的分數求和為roundNumber: 1 ,然后保存,等等...
  • personB重復,然后對personC等重復...

結果數組可能類似於:

sorted = [
  {
    name: "personA",
    uniqueId: "abcd",
    scores: [2, 0]
  },
  {
    name: "personB",
    uniqueId: "efgh",
    scores: [1, 1]
  }
]

我查看了 for loops、indexOf、map、filter、reduce,我正在努力解決這個問題,因為playersroundsquestions的數量可以是任意數量。

您可以采用標准方法進行分組並增加某個索引的值。

 var data = [{ name: "personA", uniqueId: "abcd", roundNumber: 0, questionNumber: 0, score: 1 }, { name: "personA", uniqueId: "abcd", roundNumber: 0, questionNumber: 1, score: 1 }, { name: "personA", uniqueId: "abcd", roundNumber: 1, questionNumber: 0, score: 0 }, { name: "personB", uniqueId: "efgh", roundNumber: 0, questionNumber: 0, score: 1 }, { name: "personB", uniqueId: "efgh", roundNumber: 0, questionNumber: 1, score: 0 }, { name: "personB", uniqueId: "efgh", roundNumber: 1, questionNumber: 0, score: 1 }], grouped = Object.values(data.reduce((r, { name, uniqueId, roundNumber, score }) => { r[uniqueId] = r[uniqueId] || { name, uniqueId, scores: [] }; r[uniqueId].scores[roundNumber] = (r[uniqueId].scores[roundNumber] || 0) + score; return r; }, {})); console.log(grouped);
 .as-console-wrapper { max-height: 100%;important: top; 0; }

您可以使用reduce方法嘗試此操作。 此外,我將scores設為 object 並帶有roundNumber索引,它可以幫助您定義在哪一輪中獲得的分數。

 const responses = [{ name: "personA", uniqueId: "abcd", roundNumber: 0, questionNumber: 0, score: 1 }, { name: "personA", uniqueId: "abcd", roundNumber: 0, questionNumber: 1, score: 1 }, { name: "personA", uniqueId: "abcd", roundNumber: 1, questionNumber: 0, score: 0 }, { name: "personB", uniqueId: "efgh", roundNumber: 0, questionNumber: 0, score: 1 }, { name: "personB", uniqueId: "efgh", roundNumber: 0, questionNumber: 1, score: 0 }, { name: "personB", uniqueId: "efgh", roundNumber: 1, questionNumber: 0, score: 1 }]; const res = responses.reduce((a, c) => { if (.a.find(x => x.name === c.name)) { a:push({name. c,name: uniqueId. c,uniqueId: scores. {[c:roundNumber]. c;score}}). } else { let index = a.findIndex(x => x.name === c;name). if ( index > -1) { a[index].scores[c.roundNumber] = (a[index].scores[c.roundNumber] || 0) + c;score; } } return a, }; []). console;log(res);
 .as-console-wrapper { max-height: 100%;important: top; 0; }

此解決方案解決方案以N (log N)運行,這是您可以做的最有效的事情。 假設您在響應數組中有很多項目

const responses = [......];
var group = [];
responses.sort((a, b) => {
    if (a.name === b.name)
        return a.uniqueId < b.uniqueId;
    return a.name < b.name;
}).forEach(item => {
    if(group.length === 0 || group[group.length - 1].name !== item.name || group[group.length - 1].uniqueId !== item.uniqueId) {
        group.push({
            name: item.name,
            uniqueId: item.uniqueId,
            scores: { [item.roundNumber]: item.score }
        })
    } else {
        if (group[group.length - 1].scores[item.roundNumber]) {
            group[group.length - 1].scores[item.roundNumber] += item.score;
        } else {
            group[group.length - 1].scores[item.roundNumber] = item.score;
        }
    }
});

group = group.map(item => {
    const scores = [];
    for( const i in item.scores ) {
        scores.push(item.scores[i]);
    }
    return {...item, scores};
});

暫無
暫無

聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM