簡體   English   中英

如何基於對象數組內部的對象數組返回值的總和

[英]How to return the sum of values from an array of objects based inside an array of objects

我有以下示例對象數組,數組中的每個對象都包含一個idpersonIdscores和finally score 在某些對象中, scores不為null或包含其他對象數組即分數。 在其他對象中, score可能包含一個值而不是null 最后,可能存在對象同時包含scoresscore

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)

而且,我還弄清楚了如何使用mapreduce來為該人返回score項的值:

startingArray.filter(item => item.personId === personId).map(item => item.score).reduce((a, b) => a + b, 0)

我在努力的地方是能夠對scores數組中的score項求和,該score項是針對某個人設置的。

最終,我追求的是能夠調用personScores(1)並返回人1的總得分(即69),或者調用personScores(3)並返回124(即106 + 13 + 5 )。

目前尚不清楚,一個人是否可以出現比一次更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 ),但是對於數組,我將使用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)); 

您可以使用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> 

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

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

(上面的代碼同時檢查scorescores以查看它們是否為數組,並相應地執行適當的邏輯)

暫無
暫無

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

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