'Sum of all values from a dynamic key in object array
I'm trying to sum all similar keys in an object array. Each object will have similar keys but each array may not have similar object keys. I was thinking of storing the keys in another array and looping over that but not sure the best way.
Scorecard1 input example:
let scorecard1 = [
{
"Hole": 1,
"Par": 4,
"Blue": 368,
"White": 349,
"Handicap": 16
},
{
"Hole": 2,
"Par": 4,
"Blue": 316,
"White": 305,
"Handicap": 14
},
{
"Hole": 3,
"Par": 3,
"Blue": 169,
"White": 158,
"Handicap": 10
},
{
"Hole": 4,
"Par": 4,
"Blue": 373,
"White": 351,
"Handicap": 12
},
{
"Hole": 5,
"Par": 4,
"Blue": 352,
"White": 348,
"Handicap": 6
},
{
"Hole": 6,
"Par": 5,
"Blue": 493,
"White": 485,
"Handicap": 8
},
{
"Hole": 7,
"Par": 4,
"Blue": 367,
"White": 356,
"Handicap": 18
},
{
"Hole": 8,
"Par": 3,
"Blue": 193,
"White": 176,
"Handicap": 4
},
{
"Hole": 9,
"Par": 5,
"Blue": 562,
"White": 540,
"Handicap": 2
},
{
"Hole": 10,
"Par": 4,
"Blue": 384,
"White": 369,
"Handicap": 15
},
{
"Hole": 11,
"Par": 4,
"Blue": 311,
"White": 292,
"Handicap": 11
},
{
"Hole": 12,
"Par": 4,
"Blue": 421,
"White": 411,
"Handicap": 5
},
{
"Hole": 13,
"Par": 3,
"Blue": 155,
"White": 148,
"Handicap": 17
},
{
"Hole": 14,
"Par": 5,
"Blue": 492,
"White": 483,
"Handicap": 7
},
{
"Hole": 15,
"Par": 4,
"Blue": 425,
"White": 409,
"Handicap": 1
},
{
"Hole": 16,
"Par": 5,
"Blue": 505,
"White": 479,
"Handicap": 13
},
{
"Hole": 17,
"Par": 3,
"Blue": 182,
"White": 166,
"Handicap": 9
},
{
"Hole": 18,
"Par": 4,
"Blue": 437,
"White": 427,
"Handicap": 3
}
]
Scorecard2 input example:
let scorecard2 = [
{
"Hole": 1,
"Par": 4,
"Blue": 372,
"White": 0,
"Red_Intermediate": 301,
"gold": 0,
"Handicap": 10
},
{
"Hole": 2,
"Par": 4,
"Blue": 394,
"White": 0,
"Red_Intermediate": 370,
"gold": 0,
"Handicap": 4
},
{
"Hole": 3,
"Par": 4,
"Blue": 369,
"White": 0,
"Red_Intermediate": 248,
"gold": 0,
"Handicap": 5
},
{
"Hole": 4,
"Par": 4,
"Blue": 361,
"White": 0,
"Red_Intermediate": 275,
"gold": 0,
"Handicap": 18
},
{
"Hole": 5,
"Par": 4,
"Blue": 297,
"White": 0,
"Red_Intermediate": 260,
"gold": 0,
"Handicap": 16
},
{
"Hole": 6,
"Par": 3,
"Blue": 188,
"White": 0,
"Red_Intermediate": 167,
"gold": 0,
"Handicap": 13
},
{
"Hole": 7,
"Par": 4,
"Blue": 342,
"White": 0,
"Red_Intermediate": 245,
"gold": 0,
"Handicap": 12
},
{
"Hole": 8,
"Par": 3,
"Blue": 184,
"White": 0,
"Red_Intermediate": 99,
"gold": 0,
"Handicap": 17
},
{
"Hole": 9,
"Par": 5,
"Blue": 570,
"White": 0,
"Red_Intermediate": 452,
"gold": 0,
"Handicap": 1
},
{
"Hole": 10,
"Par": 4,
"Blue": 367,
"White": 0,
"Red_Intermediate": 303,
"gold": 0,
"Handicap": 7
},
{
"Hole": 11,
"Par": 5,
"Blue": 481,
"White": 0,
"Red_Intermediate": 443,
"gold": 0,
"Handicap": 3
},
{
"Hole": 12,
"Par": 4,
"Blue": 352,
"White": 0,
"Red_Intermediate": 311,
"gold": 0,
"Handicap": 11
},
{
"Hole": 13,
"Par": 4,
"Blue": 313,
"White": 0,
"Red_Intermediate": 264,
"gold": 0,
"Handicap": 15
},
{
"Hole": 14,
"Par": 4,
"Blue": 323,
"White": 0,
"Red_Intermediate": 299,
"gold": 0,
"Handicap": 14
},
{
"Hole": 15,
"Par": 3,
"Blue": 186,
"White": 0,
"Red_Intermediate": 156,
"gold": 0,
"Handicap": 6
},
{
"Hole": 16,
"Par": 4,
"Blue": 439,
"White": 0,
"Red_Intermediate": 278,
"gold": 0,
"Handicap": 2
},
{
"Hole": 17,
"Par": 4,
"Blue": 379,
"White": 0,
"Red_Intermediate": 333,
"gold": 0,
"Handicap": 9
},
{
"Hole": 18,
"Par": 4,
"Blue": 318,
"White": 0,
"Red_Intermediate": 255,
"gold": 0,
"Handicap": 8
}
]
Scorecard.jsx
function Scorecard({ scorecard }) {
let nineHoles = scorecard.length === 9
let frontScorecard = []
let backScorecard = []
let splitScorecard = () => {
if (!nineHoles) {
var splitScorecard = Math.ceil(scorecard.length / 2)
frontScorecard = scorecard.slice(0, splitScorecard)
backScorecard = scorecard.slice(splitScorecard, scorecard.length)
} else {
frontScorecard = scorecard
}
}
splitScorecard()
let fillScorecard = (holes) => {
return (holes.map((x, i) => (
<div key={i}>
{Object.values(x).map((val, i) => (
<div className="scorecard-block" key={i}>{val}</div>
))}
</div>
)))
}
let cardStart =
<div>{Object.keys(scorecard[0]).map((x) => (
<div className="scorecard-block">
{x}
</div>
))}
</div>
let cardEndFront = <div>
{nineHoles ?
<>
<div className="scorecard-block">
In
</div>
<div className="scorecard-block">
Total
</div>
</>
:
<div className="scorecard-block">
Out
</div>
}
{Object.keys(scorecard).slice(0, 4).map((x) => (
<div className="scorecard-block">
{x}
</div>
))}
</div>
let cardEndBack = <>
<div>
<div className="scorecard-block">In</div>
{Object.keys(scorecard).slice(0, 4).map((x) => (
<div className="scorecard-block">
{x}
</div>
))}
</div>
<div>
<div className="scorecard-block">Total</div>
{Object.keys(scorecard).slice(0, 4).map((x) => (
<div className="scorecard-block">
{x}
</div>
))}
</div>
</>
return (
<>
<div className="frontnine-data-container">
{cardStart}
{fillScorecard(frontScorecard)}
{cardEndFront}
</div>
<br />
{!nineHoles && <div className="backnine-data-container">
{cardStart}
{fillScorecard(backScorecard)}
{cardEndBack}
</div>}
</>
)
Solution 1:[1]
You can use the reduce() method coupled with Object.entries() as follows:
let scorecard1 = [ { "Hole": 1, "Par": 4, "Blue": 368, "White": 349, "Handicap": 16 }, { "Hole": 2, "Par": 4, "Blue": 316, "White": 305, "Handicap": 14 }, { "Hole": 3, "Par": 3, "Blue": 169, "White": 158, "Handicap": 10 }, { "Hole": 4, "Par": 4, "Blue": 373, "White": 351, "Handicap": 12 }, { "Hole": 5, "Par": 4, "Blue": 352, "White": 348, "Handicap": 6 }, { "Hole": 6, "Par": 5, "Blue": 493, "White": 485, "Handicap": 8 }, { "Hole": 7, "Par": 4, "Blue": 367, "White": 356, "Handicap": 18 }, { "Hole": 8, "Par": 3, "Blue": 193, "White": 176, "Handicap": 4 }, { "Hole": 9, "Par": 5, "Blue": 562, "White": 540, "Handicap": 2 }, { "Hole": 10, "Par": 4, "Blue": 384, "White": 369, "Handicap": 15 }, { "Hole": 11, "Par": 4, "Blue": 311, "White": 292, "Handicap": 11 }, { "Hole": 12, "Par": 4, "Blue": 421, "White": 411, "Handicap": 5 }, { "Hole": 13, "Par": 3, "Blue": 155, "White": 148, "Handicap": 17 }, { "Hole": 14, "Par": 5, "Blue": 492, "White": 483, "Handicap": 7 }, { "Hole": 15, "Par": 4, "Blue": 425, "White": 409, "Handicap": 1 }, { "Hole": 16, "Par": 5, "Blue": 505, "White": 479, "Handicap": 13 }, { "Hole": 17, "Par": 3, "Blue": 182, "White": 166, "Handicap": 9 }, {"Hole": 18,"Par": 4,"Blue": 437,"White": 427, "Handicap": 3 }];
let scorecard2 = [ { "Hole": 1, "Par": 4, "Blue": 372, "White": 0, "Red_Intermediate": 301, "gold": 0, "Handicap": 10 }, { "Hole": 2, "Par": 4, "Blue": 394, "White": 0, "Red_Intermediate": 370, "gold": 0, "Handicap": 4 }, { "Hole": 3, "Par": 4, "Blue": 369, "White": 0, "Red_Intermediate": 248, "gold": 0, "Handicap": 5 }, { "Hole": 4, "Par": 4, "Blue": 361, "White": 0, "Red_Intermediate": 275, "gold": 0, "Handicap": 18 }, { "Hole": 5, "Par": 4, "Blue": 297, "White": 0, "Red_Intermediate": 260, "gold": 0, "Handicap": 16 }, { "Hole": 6, "Par": 3, "Blue": 188, "White": 0, "Red_Intermediate": 167, "gold": 0, "Handicap": 13 }, { "Hole": 7, "Par": 4, "Blue": 342, "White": 0, "Red_Intermediate": 245, "gold": 0, "Handicap": 12 }, { "Hole": 8, "Par": 3, "Blue": 184, "White": 0, "Red_Intermediate": 99, "gold": 0, "Handicap": 17 }, { "Hole": 9, "Par": 5, "Blue": 570, "White": 0, "Red_Intermediate": 452, "gold": 0, "Handicap": 1 }, { "Hole": 10, "Par": 4, "Blue": 367, "White": 0, "Red_Intermediate": 303, "gold": 0, "Handicap": 7 }, { "Hole": 11, "Par": 5, "Blue": 481, "White": 0, "Red_Intermediate": 443, "gold": 0, "Handicap": 3 }, { "Hole": 12, "Par": 4, "Blue": 352, "White": 0, "Red_Intermediate": 311, "gold": 0, "Handicap": 11 }, { "Hole": 13, "Par": 4, "Blue": 313, "White": 0, "Red_Intermediate": 264, "gold": 0, "Handicap": 15 }, { "Hole": 14, "Par": 4, "Blue": 323, "White": 0, "Red_Intermediate": 299, "gold": 0, "Handicap": 14 }, { "Hole": 15, "Par": 3, "Blue": 186, "White": 0, "Red_Intermediate": 156, "gold": 0, "Handicap": 6 }, { "Hole": 16, "Par": 4, "Blue": 439, "White": 0, "Red_Intermediate": 278, "gold": 0, "Handicap": 2 }, { "Hole": 17, "Par": 4, "Blue": 379, "White": 0, "Red_Intermediate": 333, "gold": 0, "Handicap": 9 }, { "Hole": 18, "Par": 4, "Blue": 318, "White": 0, "Red_Intermediate": 255, "gold": 0, "Handicap": 8 }];
const totals = scoreboard => scoreboard.reduce(
(prev,cur,i) => i === 0 ? cur :
Object.entries(cur).reduce(
(ac,[key,value]) => ({...ac,[key]:value+prev[key]}), {}
),{}
);
console.log( totals( scorecard1 ) );
console.log( totals( scorecard2 ) );
console.log( [scorecard1, scorecard2].map(s => totals( s )) );
Sources
This article follows the attribution requirements of Stack Overflow and is licensed under CC BY-SA 3.0.
Source: Stack Overflow
| Solution | Source |
|---|---|
| Solution 1 |
