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>}
</>
)
CodePudding user response:
This should work, note, it ignores 'Hole' for obvious reasons
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}];
function scoreTotal(arr) {
const addem = array => array.reduce((acc,obj) => {
Object.entries(obj)
.filter(([key]) => key !== 'Hole')
.forEach(([key, value]) => acc[key] = (acc[key] || 0) value);
return acc;
}, {});
const out9 = addem(scorecard1.slice(0,9));
const in9 = addem(scorecard1.slice(9));
const total = addem([out9, in9]);
return { out9, in9, total };
}
console.log(scoreTotal(scorecard1));
The function returns an object with out9, in9 and total properties
CodePudding user response:
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
}
];
const totals = scoreboard => scoreboard.reduce(
(prev,cur,i) => i === 0 ? cur :
Object.entries(cur).reduce(
(ac,cu) => ({...ac,[cu[0]]:cu[1] prev[cu[0]]}), {}
),{}
);
console.log( totals( scorecard1 ) );