Reputation: 1336
I have a JSON file and I would like this JSON to be grouped by according to three fields in it.
The JSON looks as follow(with more items of course):
{
"Racename": "10KM",
"Category": 34,
"Gender": "Male",
"Work": "Google",
"FullName": "Dave Happner",
"Rank": 1,
"Ponit": 1,
"Numparticipant": 0,
"rankparticipant": 0,
"precentagePart": "0",
"NumRaces": 1,
"RaceTime": "2018-10-18T00:34:20",
"rankCat": 1,
"PointCat": 1,
"RaceDate": "2018-10-05"
}
The requested result (using underscore
or lodash
) is:
[
{
"Racename" : "10KM",
"Category": "34",
"Gender": "Male",
runner : [
{
"Work": "Google",
"FullName": "Dave Happner",
"Rank": 1,
"Ponit": 1,
"Numparticipant": 0,
"rankparticipant": 0,
"precentagePart": "0",
"NumRaces": 1,
"RaceTime": "2018-10-18T00:34:20",
"rankCat": 1,
"PointCat": 1,
"RaceDate": "2018-10-05"
}]
Upvotes: 1
Views: 72
Reputation: 370949
You can reduce
into an object indexed by a string, made up of the Racename
, Category
, and Gender
, joined by a character that won't be present in the values, such as _
. For example, your input in the question would result in an object with a key of 10KM_34_Male
. On every iteration, check to see if the constructed key exists - if it doesn't, create the object, with an empty runner
array. Then, push to the runner
array.
After you've finished with the reduce
, you can get the object's values to get your desired array output:
const input = [{
"Racename": "10KM",
"Category": 34,
"Gender": "Male",
"Work": "Google",
"FullName": "Dave Happner",
"Rank": 1,
"Ponit": 1,
"Numparticipant": 0,
"rankparticipant": 0,
"precentagePart": "0",
"NumRaces": 1,
"RaceTime": "2018-10-18T00:34:20",
"rankCat": 1,
"PointCat": 1,
"RaceDate": "2018-10-05"
}];
const outputObj = input.reduce((a, { Racename, Category, Gender, ...rest }) => {
const key = [Racename, Category, Gender].join('_');
if (!a[key]) {
a[key] = { Racename, Category, Gender, runner: [] };
}
a[key].runner.push(rest);
return a;
}, {});
const output = Object.values(outputObj);
console.log(output);
Or, using a larger input:
const input = [{
"Racename": "10KM",
"Category": 34,
"Gender": "Male",
"Work": "Google",
"FullName": "Dave Happner",
"Rank": 1,
"Ponit": 1,
"Numparticipant": 0,
"rankparticipant": 0,
"precentagePart": "0",
"NumRaces": 1,
"RaceTime": "2018-10-18T00:34:20",
"rankCat": 1,
"PointCat": 1,
"RaceDate": "2018-10-05"
},{
"Racename": "10KM",
"Category": 34,
"Gender": "Male",
"Work": "Amazon",
"FullName": "Bob Joe",
"Rank": 12,
"Ponit": 2,
"Numparticipant": 0,
"rankparticipant": 0,
"precentagePart": "0",
"NumRaces": 1,
"RaceTime": "2018-10-18T00:34:20",
"rankCat": 1,
"PointCat": 1,
"RaceDate": "2018-10-05"
},{
"Racename": "20KM",
"Category": 40,
"Gender": "Male",
"Work": "Google",
"FullName": "Dave Happner",
"Rank": 1,
"Ponit": 1,
"Numparticipant": 0,
"rankparticipant": 0,
"precentagePart": "0",
"NumRaces": 1,
"RaceTime": "2018-10-18T00:34:20",
"rankCat": 1,
"PointCat": 1,
"RaceDate": "2018-10-05"
}
];
const outputObj = input.reduce((a, { Racename, Category, Gender, ...rest }) => {
const key = [Racename, Category, Gender].join('_');
if (!a[key]) {
a[key] = { Racename, Category, Gender, runner: [] };
}
a[key].runner.push(rest);
return a;
}, {});
const output = Object.values(outputObj);
console.log(output);
Upvotes: 1