我有以下示例对象数组,数组中的每个对象都包含一个 id
、personId
、scores
以及最后的 得分
。在某些对象中,scores
要么为 null
,要么包含另一个作为分数的对象数组。在其他对象中,score
可能包含一个值,而不是 null
。最后,可能存在对象可以同时包含 scores
和 score
的情况。
const startingArray = [
{
id: 1,
personId: 1,
scores: [
{
id: 1,
title: 'Google',
score: 12
},
{
id: 2,
title: 'Bing',
score: 23
},
{
id: 3,
title: 'Facebook',
score: 34
}
],
score: null
},
{
id: 2,
personId: 1,
scores: null,
score: 123
},
{
id: 3,
personId: 2,
scores: [
{
id: 4,
title: 'Google',
score: 7
},
{
id: 5,
title: 'Bing',
score: 32
},
{
id: 6,
title: 'Facebook',
score: 9
}
],
score: null
},
{
id: 4,
personId: 3,
scores: null,
score: 106
},
{
id: 5,
personId: 3,
scores: [
{
id: 7,
title: 'Google',
score: 6
},
{
id: 8,
title: 'Bing',
score: 4
},
{
id: 9,
title: 'Facebook',
score: 3
}
],
score: 5
}
]
我可以过滤 startingArray
以返回一个人的有效对象:
startingArray.filter(item => item.personId === personId)
我还弄清楚了如何使用 map
和 reduce
来返回该人的 score
项的值:
startingArray.filter(item => item.personId === personId).map(item => item.score).reduce((a, b) => a + b, 0)
我正在努力的地方是能够对针对一个人设置的 scores
数组中的 score
项进行求和。
最终我想要的是能够调用 personScores(1)
并返回第 1 个人的总分(即 69),或者调用 personScores(3 )
它将返回 124(即 106 + 13 + 5)。
最佳答案
尚不清楚一个人是否可以在 startingArray
中出现多次。假设它们可以出现多次:
一种流行的方法是使用Array#reduce
,但我只使用几个for-of
循环。您不需要预先过滤
(尽管有些人更喜欢这样做,这很好)。
这是for-of
版本:
function personScore(personId) {
let sum = 0;
for (const entry of startingArray) {
if (entry.personId === personId) {
sum += entry.score || 0;
if (entry.scores) {
for (const {score} of entry.scores) {
sum += score;
}
}
}
}
return sum;
}
实时复制:
const startingArray = [
{
id: 1,
personId: 1,
scores: [
{
id: 1,
title: 'Google',
score: 12
},
{
id: 2,
title: 'Bing',
score: 23
},
{
id: 3,
title: 'Facebook',
score: 34
}
],
score: null
},
{
id: 2,
personId: 1,
scores: null,
score: 123
},
{
id: 3,
personId: 2,
scores: [
{
id: 4,
title: 'Google',
score: 7
},
{
id: 5,
title: 'Bing',
score: 32
},
{
id: 6,
title: 'Facebook',
score: 9
}
],
score: null
},
{
id: 4,
personId: 3,
scores: null,
score: 106
},
{
id: 5,
personId: 3,
scores: [
{
id: 7,
title: 'Google',
score: 6
},
{
id: 8,
title: 'Bing',
score: 4
},
{
id: 9,
title: 'Facebook',
score: 3
}
],
score: 5
}
]
function personScore(personId) {
let sum = 0;
for (const entry of startingArray) {
if (entry.personId === personId) {
sum += entry.score || 0;
if (entry.scores) {
for (const {score} of entry.scores) {
sum += score;
}
}
}
}
return sum;
}
console.log(personScore(1));
这是reduce
版本:
function personScore(personId) {
return startingArray.reduce((sum, entry) => {
if (entry.personId !== personId) {
return sum;
}
sum += entry.score || 0;
if (entry.scores) {
sum += entry.scores.reduce((acc, {score}) => acc + score, 0);
}
return sum;
}, 0);
}
实时复制:
const startingArray = [
{
id: 1,
personId: 1,
scores: [
{
id: 1,
title: 'Google',
score: 12
},
{
id: 2,
title: 'Bing',
score: 23
},
{
id: 3,
title: 'Facebook',
score: 34
}
],
score: null
},
{
id: 2,
personId: 1,
scores: null,
score: 123
},
{
id: 3,
personId: 2,
scores: [
{
id: 4,
title: 'Google',
score: 7
},
{
id: 5,
title: 'Bing',
score: 32
},
{
id: 6,
title: 'Facebook',
score: 9
}
],
score: null
},
{
id: 4,
personId: 3,
scores: null,
score: 106
},
{
id: 5,
personId: 3,
scores: [
{
id: 7,
title: 'Google',
score: 6
},
{
id: 8,
title: 'Bing',
score: 4
},
{
id: 9,
title: 'Facebook',
score: 3
}
],
score: 5
}
]
function personScore(personId) {
return startingArray.reduce((sum, entry) => {
if (entry.personId !== personId) {
return sum;
}
sum += entry.score || 0;
if (entry.scores) {
sum += entry.scores.reduce((acc, {score}) => acc + score, 0);
}
return sum;
}, 0);
}
console.log(personScore(1));
如果它们只能出现一次,数组确实不是组织数据的方式(我会使用对象或 Map
),但对于数组,我会使用 find
找到它们,然后从该条目中获取信息:
function personScore(personId) {
const entry = startingArray.find(entry => entry.personId === personId);
if (!entry) {
return 0;
}
let sum = entry.score || 0;
if (entry.scores) {
for (const {score} of scores) {
sum += score;
}
}
return sum;
}
实时复制:
const startingArray = [
{
id: 1,
personId: 1,
scores: [
{
id: 1,
title: 'Google',
score: 12
},
{
id: 2,
title: 'Bing',
score: 23
},
{
id: 3,
title: 'Facebook',
score: 34
}
],
score: null
},
{
id: 2,
personId: 1,
scores: null,
score: 123
},
{
id: 3,
personId: 2,
scores: [
{
id: 4,
title: 'Google',
score: 7
},
{
id: 5,
title: 'Bing',
score: 32
},
{
id: 6,
title: 'Facebook',
score: 9
}
],
score: null
},
{
id: 4,
personId: 3,
scores: null,
score: 106
},
{
id: 5,
personId: 3,
scores: [
{
id: 7,
title: 'Google',
score: 6
},
{
id: 8,
title: 'Bing',
score: 4
},
{
id: 9,
title: 'Facebook',
score: 3
}
],
score: 5
}
]
function personScore(personId) {
const entry = startingArray.find(entry => entry.personId === personId);
if (!entry) {
return 0;
}
let sum = entry.score || 0;
if (entry.scores) {
for (const {score} of scores) {
sum += score;
}
}
return sum;
}
console.log(personScore(1));
关于javascript - 如何从基于对象数组内部的对象数组返回值的总和,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/56644319/