[英]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
的所有對象(使用它們的name
和uniqueId
字段),然后通過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,我正在努力解決這個問題,因為players
、 rounds
或questions
的數量可以是任意數量。
您可以采用標准方法進行分組並增加某個索引的值。
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.