我有以下示例对象数组,该数组中的每个对象都包含一个image classification
,id
,personId
,最后是scores
。在某些对象中,score
是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)
数组中与某人相对应的score
个项目求和。
最终,我所追求的是能够打电话给scores
并返回人1的总分(即69),或者打电话给personScores(1)
并返回124(即106 + 13 + 5)。
答案 0 :(得分:4)
尚不清楚一个人是否可以在startingArray
中出现多次。假设它们可以出现多次:
一种流行的方法是使用Array#reduce
,但是我只会使用几个for-of
循环。您无需预先{filter
(尽管有些人更喜欢,这很好)。
这是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
),但是对于数组,我将使用{{1} }找到它们,然后只需从该条目中获取信息:
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;
}
答案 1 :(得分:1)
您可以使用reduce来获得总和,或者如果我们有一个分数数组,可以再次使用reduce,或者简单地添加在score处的值
function getPersonScore(arr, id) {
const filtered = id ? arr.filter(e => e.personId === id) : arr;
return filtered.reduce((a, b) => {
if (Array.isArray(b.scores)) a += getPersonScore(b.scores);
return a + (b.score || 0);
}, 0);
}
console.log(getPersonScore(startingArray, 1));
<script>
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
}
];
</script>
答案 2 :(得分:0)
const personScores = (id, arr) => {
// error catching
if (!Array.isArray(arr)) {
throw new Error('Input array is not an array');
}
if (id >= arr.length) {
throw new Error(`Id ${id} out of array range (length ${arr.length})`);
}
if (!('scores' in arr[id])) {
throw new Error(`scores key missing in input array`);
}
if (!Array.isArray(arr[id].scores)) {
throw new Error(`Scores of input id ${id} not an array`);
}
// iterate scores array of startingArray[id], defaultValue of sum is 0
return arr[id].scores.reduce((sum, scoreObj) => {
if ('score' in scoreObj && !isNaN(parseInt(scoreObj.score, 10))) {
sum += parseInt(scoreObj.score, 10);
}
return sum;
}, 0); // defaultValue of the reducer
};
答案 3 :(得分:0)
首先find
您想要的人,然后使用reduce
添加他们的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}];
const personScores = id => {
let { scores, score } = startingArray.find(({ personId }) => personId);
let finalScore = 0;
if (score && score.length) finalScore += (Array.isArray(score) ? score.reduce((a, { score }) => a + score, 0) : score);
if (scores && scores.length) finalScore += (Array.isArray(scores) ? scores.reduce((a, { score }) => a + score, 0) : scores);
return finalScore;
};
console.log(personScores(1));
console.log(personScores(3));
(上面的代码检查score
和scores
两者是否为数组,并相应地执行适当的逻辑)