I have an array of objects
that can have three forms:
First form is as follows (where is just one record per roundId
):
[{
"roundId": "b382935b-fe84-4b8c-97e0-eb0b215c68c5",
"teamId": null,
"score": null
},
{
"roundId": "d7f7d3be-cab0-45a6-965f-73f26eb39692",
"teamId": null,
"score": null
},
{
"roundId": "f6aed9f1-5b8a-4da1-aeff-13620aee9c76",
"teamId": null,
"score": null
}
]
And the second form can be like this (where there can be two records and one record per roundId
):
[{
"roundId": "4fc1753a-38ca-4cd4-a772-620d86c35916",
"teamId": "fc6295c4-8527-4329-a3aa-373d854a04c8",
"score": 21
},
{
"roundId": "4fc1753a-38ca-4cd4-a772-620d86c35916",
"teamId": "2e7fcc40-ac45-419b-a80d-a7713a5d6ce0",
"score": 20
},
{
"roundId": "62d0f2a1-be7a-4742-91bc-5a83cf408728",
"teamId": "fc6295c4-8527-4329-a3aa-373d854a04c8",
"score": 18
},
{
"roundId": "62d0f2a1-be7a-4742-91bc-5a83cf408728",
"teamId": "2e7fcc40-ac45-419b-a80d-a7713a5d6ce0",
"score": 7
},
{
"roundId": "d600bdc1-dbd7-4683-9d20-581e4f759ccb",
"teamId": null,
"score": null
}
]
And the last form (where there can be two records for a roundId
):
[{
"roundId": "4fc1753a-38ca-4cd4-a772-620d86c35916",
"teamId": "fc6295c4-8527-4329-a3aa-373d854a04c8",
"score": 21
},
{
"roundId": "4fc1753a-38ca-4cd4-a772-620d86c35916",
"teamId": "2e7fcc40-ac45-419b-a80d-a7713a5d6ce0",
"score": 20
},
{
"roundId": "62d0f2a1-be7a-4742-91bc-5a83cf408728",
"teamId": "fc6295c4-8527-4329-a3aa-373d854a04c8",
"score": 18
},
{
"roundId": "62d0f2a1-be7a-4742-91bc-5a83cf408728",
"teamId": "2e7fcc40-ac45-419b-a80d-a7713a5d6ce0",
"score": 7
},
{
"roundId": "d600bdc1-dbd7-4683-9d20-581e4f759ccb",
"teamId": "fc6295c4-8527-4329-a3aa-373d854a04c8",
"score": 19
},
{
"roundId": "d600bdc1-dbd7-4683-9d20-581e4f759ccb",
"teamId": "2e7fcc40-ac45-419b-a80d-a7713a5d6ce0",
"score": 12
}
]
I need that based on the roundId key
to return a new array of objects, where an object is formed of two keys: roundId
and teams
where teams
is an array of objects formed of teamdId
and score
.
If the teamId and score are null
the array of objects should be like:
[
{
"roundId": "b382935b-fe84-4b8c-97e0-eb0b215c68c5",
"teams": []
},
{
"roundId": "d7f7d3be-cab0-45a6-965f-73f26eb39692",
"teams": []
},
{
"roundId": "f6aed9f1-5b8a-4da1-aeff-13620aee9c76",
"teams": []
}
]
If there are teamId
and score
for a roundId
I have to return:
[
{
"roundId": "4fc1753a-38ca-4cd4-a772-620d86c35916",
"teams": [
{ "teamId": "fc6295c4-8527-4329-a3aa-373d854a04c8", "score": 21 },
{ "teamId": "2e7fcc40-ac45-419b-a80d-a7713a5d6ce0", "score": 20 },
},
{
"roundId": "62d0f2a1-be7a-4742-91bc-5a83cf408728",
"teams": [
{ "teamId": "fc6295c4-8527-4329-a3aa-373d854a04c8", "score": 18 },
{ "teamId": "2e7fcc40-ac45-419b-a80d-a7713a5d6ce0", "score": 7 },
},
{
"roundId": "d600bdc1-dbd7-4683-9d20-581e4f759ccb",
"teams": [
{ "teamId": "fc6295c4-8527-4329-a3aa-373d854a04c8", "score": 19 },
{ "teamId": "2e7fcc40-ac45-419b-a80d-a7713a5d6ce0", "score": 12 },
}
]
I tried that using reduce
but I got it wrong:
const finalResult = matchesRoundsScore.reduce((result, currentValue) => {
const foundRound = result.find(item => item.roundId === currentValue.roundId)
if (!foundRound) {
result.push({
roundId: currentValue.roundId,
teams: []
})
} else {
result.push({
roundId: currentValue.roundId,
teams: new Array(currentValue.teamId, currentValue.score)
})
}
}, [])
Thank you for your time! Let me know if something is unclear!
CodePudding user response:
This could be an option, using Map
to merge records with same roundId
const merge = input => [...input.reduce((m, {roundId, teamId, score}) => {
if (!m.has(roundId)) {
m.set(roundId, []);
}
if (teamId) {
m.get(roundId).push({teamId, score});
}
return m;
}, new Map())].map(([roundId, m]) => ({roundId, teams: [...m]}));
const input = [
{
"roundId": "4fc1753a-38ca-4cd4-a772-620d86c35916",
"teamId": "fc6295c4-8527-4329-a3aa-373d854a04c8",
"score": 21
},
{
"roundId": "4fc1753a-38ca-4cd4-a772-620d86c35916",
"teamId": "2e7fcc40-ac45-419b-a80d-a7713a5d6ce0",
"score": 20
},
{
"roundId": "62d0f2a1-be7a-4742-91bc-5a83cf408728",
"teamId": "fc6295c4-8527-4329-a3aa-373d854a04c8",
"score": 18
},
{
"roundId": "62d0f2a1-be7a-4742-91bc-5a83cf408728",
"teamId": "2e7fcc40-ac45-419b-a80d-a7713a5d6ce0",
"score": 7
},
{
"roundId": "d600bdc1-dbd7-4683-9d20-581e4f759ccb",
"teamId": null,
"score": null
}
];
console.log(merge(input));
CodePudding user response:
Below is one possible way to achieve the target.
Code Snippet
// method to group data by "roundId"
const groupByRounds = arr => (
// implict-return by extracting "values" of the intermediate result object
Object.values(
arr.reduce( // iterate using "reduce" to generate result-object
(acc, {roundId, teamId, score}) => { // de-structure to access props
acc[roundId] = ({ // create/update value for key: "roundId"
roundId,
teams: (acc[roundId]?.teams ?? []).concat((
teamId && score // if "teamId" and "score" are both truthy
? [{ teamId, score }] // add them to the array
: [] // else, it's an empty array
))
})
return acc; // "acc" is the accumulator / agrregator
},
{} // initial value of "acc" is empty object {}
)
)
);
const dataType0 = [{
"roundId": "b382935b-fe84-4b8c-97e0-eb0b215c68c5",
"teamId": null,
"score": null
},
{
"roundId": "d7f7d3be-cab0-45a6-965f-73f26eb39692",
"teamId": null,
"score": null
},
{
"roundId": "f6aed9f1-5b8a-4da1-aeff-13620aee9c76",
"teamId": null,
"score": null
}
];
const dataType1 = [{
"roundId": "4fc1753a-38ca-4cd4-a772-620d86c35916",
"teamId": "fc6295c4-8527-4329-a3aa-373d854a04c8",
"score": 21
},
{
"roundId": "4fc1753a-38ca-4cd4-a772-620d86c35916",
"teamId": "2e7fcc40-ac45-419b-a80d-a7713a5d6ce0",
"score": 20
},
{
"roundId": "62d0f2a1-be7a-4742-91bc-5a83cf408728",
"teamId": "fc6295c4-8527-4329-a3aa-373d854a04c8",
"score": 18
},
{
"roundId": "62d0f2a1-be7a-4742-91bc-5a83cf408728",
"teamId": "2e7fcc40-ac45-419b-a80d-a7713a5d6ce0",
"score": 7
},
{
"roundId": "d600bdc1-dbd7-4683-9d20-581e4f759ccb",
"teamId": null,
"score": null
}
];
const dataType2 = [{
"roundId": "4fc1753a-38ca-4cd4-a772-620d86c35916",
"teamId": "fc6295c4-8527-4329-a3aa-373d854a04c8",
"score": 21
},
{
"roundId": "4fc1753a-38ca-4cd4-a772-620d86c35916",
"teamId": "2e7fcc40-ac45-419b-a80d-a7713a5d6ce0",
"score": 20
},
{
"roundId": "62d0f2a1-be7a-4742-91bc-5a83cf408728",
"teamId": "fc6295c4-8527-4329-a3aa-373d854a04c8",
"score": 18
},
{
"roundId": "62d0f2a1-be7a-4742-91bc-5a83cf408728",
"teamId": "2e7fcc40-ac45-419b-a80d-a7713a5d6ce0",
"score": 7
},
{
"roundId": "d600bdc1-dbd7-4683-9d20-581e4f759ccb",
"teamId": "fc6295c4-8527-4329-a3aa-373d854a04c8",
"score": 19
},
{
"roundId": "d600bdc1-dbd7-4683-9d20-581e4f759ccb",
"teamId": "2e7fcc40-ac45-419b-a80d-a7713a5d6ce0",
"score": 12
}
];
console.log('data of type 0', groupByRounds(dataType0));
console.log('data of type 1', groupByRounds(dataType1));
console.log('data of type 2', groupByRounds(dataType2));
/*
console.log(
'data of type combined',
groupByRounds([
...dataType0, ...dataType1, ...dataType2
])
);
*/
.as-console-wrapper { max-height: 100% !important; top: 0 }
Explanation
Inline comments added in the snippet above.