Hi I am having an array like this
Given Data
[
{
"id": "Client 1",
"mName": "SDk",
"cName": "Thor Odin",
"gName": "",
"gAmt": 80000,
"gls": 2,
"value": 0.855,
"date": "22/1/2022",
"income": "",
"subRows": [
{
"id": "goal-1",
"cName": "",
"mName": "",
"gName": "Retirement1",
"gAmt": 10000,
"gls": 1,
"income": "60/40",
"date": "22/1/2022",
"value": 0.99
},
{
"id": "goal-2",
"cName": "",
"mName": "",
"gName": "Save For Child Education",
"gAmt": 70000,
"gls": 1,
"income": "55/45",
"date": "5/12/2023",
"value": 0.72
}
]
},
{
"id": "Client 2",
"mName": "SDk",
"cName": "Steve Rogers",
"gName": "Save for Investment",
"gAmt": 67000,
"gls": 1,
"value": 0.7,
"date": "22/1/2022",
"income": "60/40"
},
{
"id": "Client 3",
"mName": "Pal",
"cName": "Wanda Vision",
"gls": 0,
"value": 0.9,
"date": "",
"income": ""
},
{
"id": "Client 4",
"mName": "Pal",
"cName": "Tony Stark",
"gName": "",
"gAmt": 23500,
"gls": 2,
"value": 0.29,
"date": "27/10/2019",
"income": "",
"subRows": [
{
"id": "goal-4",
"cName": "",
"mName": "",
"gName": "Education Loan",
"gAmt": 500,
"gls": 1,
"income": "60/40",
"date": "27/10/2019",
"value": 0.29
},
{
"id": "goal-5",
"cName": "",
"mName": "",
"gName": "House Loan",
"gAmt": 23000,
"gls": 1,
"income": "30/70",
"date": "16/6/2022",
"value": 0.29
}
]
},
{
"id": "Client 5",
"mName": "Joe",
"cName": "Hack Eye",
"gName": "Save For World Tour",
"gAmt": 400000,
"gls": 1,
"value": 0.74,
"date": "",
"income": "60/40"
},
{
"id": "Client 6",
"mName": "Joe",
"cName": "Nick Fury",
"gName": "",
"gAmt": 51070,
"gls": 2,
"value": 0.44499999999999995,
"date": "9/3/2022",
"income": "",
"subRows": [
{
"id": "goal-7",
"cName": "",
"mName": "",
"gName": "To Build A Workspace",
"gAmt": 42340,
"gls": 1,
"income": "60/40",
"date": "9/3/2022",
"value": 0.6
},
{
"id": "goal-8",
"cName": "",
"mName": "",
"gName": "Cloud Examination",
"gAmt": 8730,
"gls": 1,
"income": "30/70",
"date": "9/11/2021",
"value": 0.29
}
]
}
]
And I need to convert the above array into like this
[
{
"mName": "SDk",
"id": "",
"cName": "",
"gName": "",
"gAmt": "",
"gls": "",
"value": "",
"date": "",
"income": "",
"subRows": [
{
"mName": "",
"id": "Client 1",
"cName": "Thor Odin",
"gName": "",
"gAmt": 80000,
"gls": 2,
"value": 0.855,
"date": "22/1/2022",
"income": "",
"subRows": [
{
"id": "goal-1",
"cName": "",
"mName": "",
"gName": "Retirement1",
"gAmt": 10000,
"gls": 1,
"income": "60/40",
"date": "22/1/2022",
"value": 0.99
},
{
"id": "goal-2",
"cName": "",
"mName": "",
"gName": "Save For Child Education",
"gAmt": 70000,
"gls": 1,
"income": "55/45",
"date": "5/12/2023",
"value": 0.72
}
]
},
{
"mName": "",
"id": "Client 2",
"cName": "Steve Rogers",
"gName": "Save for Investment",
"gAmt": 67000,
"gls": 1,
"value": 0.7,
"date": "22/1/2022",
"income": "60/40"
},
{
"mName": "",
"id": "Client 3",
"cName": "Wanda Vision",
"gls": 0,
"value": 0.9,
"date": "",
"income": ""
},
{
"mName": "",
"id": "Client 4",
"cName": "Tony Stark",
"gName": "",
"gAmt": 23500,
"gls": 2,
"value": 0.29,
"date": "27/10/2019",
"income": "",
"subRows": [
{
"id": "goal-4",
"cName": "",
"mName": "",
"gName": "Education Loan",
"gAmt": 500,
"gls": 1,
"income": "60/40",
"date": "27/10/2019",
"value": 0.29
},
{
"id": "goal-5",
"cName": "",
"mName": "",
"gName": "House Loan",
"gAmt": 23000,
"gls": 1,
"income": "30/70",
"date": "16/6/2022",
"value": 0.29
}
]
}
]
},
{
"mName": "Joe",
"id": "",
"cName": "",
"gName": "",
"gAmt": "",
"gls": "",
"value": "",
"date": "",
"income": "",
"subRows": [
{
"mName": "",
"id": "Client 5",
"cName": "Hack Eye",
"gName": "Save For World Tour",
"gAmt": 400000,
"gls": 1,
"value": 0.74,
"date": "",
"income": "60/40"
},
{
"mName": "",
"id": "Client 6",
"cName": "Nick Fury",
"gName": "",
"gAmt": 51070,
"gls": 2,
"value": 0.44499999999999995,
"date": "9/3/2022",
"income": "",
"subRows": [
{
"id": "goal-7",
"cName": "",
"mName": "",
"gName": "To Build A Workspace",
"gAmt": 42340,
"gls": 1,
"income": "60/40",
"date": "9/3/2022",
"value": 0.6
},
{
"id": "goal-8",
"cName": "",
"mName": "",
"gName": "Cloud Examination",
"gAmt": 8730,
"gls": 1,
"income": "30/70",
"date": "9/11/2021",
"value": 0.29
}
]
},
{
"mName": "",
"id": "Client 7",
"cName": "Star Lord",
"gName": "Save For Child Education",
"gAmt": 400000,
"gls": 1,
"value": 0.93,
"date": "",
"income": "55/45"
}
]
},
{
"mName": "Pal",
"id": "",
"cName": "",
"gName": "",
"gAmt": "",
"gls": "",
"value": "",
"date": "",
"income": "",
"subRows": [
{
"mName": "",
"id": "Client 8",
"cName": "Thanos",
"gName": "",
"gAmt": 1200000,
"gls": 3,
"value": 0.29,
"date": "2/11/2019",
"income": "",
"subRows": [
{
"id": "goal-10",
"cName": "",
"mName": "",
"gName": "Relocation Expense Goal",
"gAmt": 400000,
"gls": 1,
"income": "22/78",
"date": "2/11/2019",
"value": 0.29
},
{
"id": "goal-11",
"cName": "",
"mName": "",
"gName": "Save for to buy bike",
"gAmt": 400000,
"gls": 1,
"income": "50/50",
"date": "1/1/2020",
"value": 0.29
},
{
"id": "goal-12",
"cName": "",
"mName": "",
"gName": "Save For Education",
"gAmt": 400000,
"gls": 1,
"income": "65/35",
"date": "9/5/2022",
"value": 0.29
}
]
},
{
"mName": "",
"id": "Client 9",
"cName": "Ego",
"gName": "Save For Education",
"gAmt": 400000,
"gls": 1,
"value": 0.72,
"date": "",
"income": "65/35"
},
{
"mName": "",
"id": "Client 10",
"cName": "Bruce Banner",
"gName": "",
"gAmt": 27600,
"gls": 2,
"value": 0.975,
"date": "9/10/2018",
"income": "",
"subRows": [
{
"id": "goal-14",
"cName": "",
"mName": "",
"gName": "Car Loan",
"gAmt": 23000,
"gls": 1,
"income": "60/40",
"date": "9/10/2018",
"value": 0.99
},
{
"id": "goal-15",
"cName": "",
"mName": "",
"gName": "Bike Loan",
"gAmt": 4600,
"gls": 1,
"income": "30/70",
"date": "9/11/2021",
"value": 0.96
}
]
}
]
}
]
The below function works fine on converting the given data into the desired format.
const emptyNode = {
mName: "",
id: "",
cName: "",
gName: "",
gAmt: "",
gls: "",
value: "",
date: "",
income: "",
subRows: [],
};
const groupsByMName = data.reduce((acc, item) => {
acc[item.mName] ??= [];
acc[item.mName].push({ ...item, mName: "" });
return acc;
}, {});
const arrExpected = Object.entries(groupsByMName)
.map(([mName, subRows]) => ({ ...emptyNode, mName, subRows }));
But, Is there a way we can make this function reusable by accepting the key dynamically? Currently, this function works only for mName
. If we want to group by some other key means. is that possible
My Tries
Dynamic Key Passing
I could able to pass the key upto the first level of the function.
Usind this
let dynamicKey = 'managerName'
const groupsByMangerName = data.reduce((acc, item) => {
acc[item[dynamicKey]] ??= [];
acc[item[dynamicKey]].push({ ...item, [dynamicKey]: "" });
return acc;
}, {});
But not able to pass this into the below section:
const arrExpected = Object.entries(groupsByMName)
.map(([mName, subRows]) => ({ ...emptyNode, mName, subRows }));
Multi Level Nesting:
const data = [{"id":"Client 1","advisorName":"Dhanush","managerName":"Nikolai","clientName":"Thor Odin","goalName":"","goalAmount":"","goals":2,"score":0.855,"lastModified":"22/1/2022","equityFixedIncome":"","subRows":[{"id":"goal-1","clientName":"","managerName":"","advisorName":"","goalName":"Retirement1","goalAmount":10000,"goals":1,"equityFixedIncome":"60/40","lastModified":"22/1/2022","score":0.99},{"id":"goal-2","clientName":"","managerName":"","advisorName":"","goalName":"Save For Child Education","goalAmount":70000,"goals":1,"equityFixedIncome":"55/45","lastModified":"5/12/2023","score":0.72}]},{"id":"Client 2","advisorName":"Dhanush","managerName":"Nikolai","clientName":"Steve Rogers","goalName":"Save for Investment","goalAmount":67000,"goals":1,"score":0.7,"lastModified":"22/1/2022","equityFixedIncome":"60/40"},{"id":"Client 3","advisorName":"Dhanush","managerName":"Nikolai","clientName":"Wanda Vision","goals":0,"score":0.9,"lastModified":"","equityFixedIncome":""},{"id":"Client 4","advisorName":"Dhanush","managerName":"Nikolai","clientName":"Tony Stark","goalName":"","goalAmount":"","goals":2,"score":0.29,"lastModified":"27/10/2019","equityFixedIncome":"","subRows":[{"id":"goal-4","clientName":"","managerName":"","advisorName":"","goalName":"Education Loan","goalAmount":500,"goals":1,"equityFixedIncome":"60/40","lastModified":"27/10/2019","score":0.29},{"id":"goal-5","clientName":"","managerName":"","advisorName":"","goalName":"House Loan","goalAmount":23000,"goals":1,"equityFixedIncome":"30/70","lastModified":"16/6/2022","score":0.29}]},{"id":"Client 5","advisorName":"Joe","managerName":"Nikolai","clientName":"Hack Eye","goalName":"Save For World Tour","goalAmount":400000,"goals":1,"score":0.74,"lastModified":"","equityFixedIncome":"60/40"},{"id":"Client 6","advisorName":"Joe","managerName":"Nikolai","clientName":"Nick Fury","goalName":"","goalAmount":"","goals":2,"score":0.44499999999999995,"lastModified":"9/3/2022","equityFixedIncome":"","subRows":[{"id":"goal-7","clientName":"","managerName":"","advisorName":"","goalName":"To Build A Workspace","goalAmount":42340,"goals":1,"equityFixedIncome":"60/40","lastModified":"9/3/2022","score":0.6},{"id":"goal-8","clientName":"","managerName":"","advisorName":"","goalName":"Cloud Examination","goalAmount":8730,"goals":1,"equityFixedIncome":"30/70","lastModified":"9/11/2021","score":0.29}]},{"id":"Client 7","advisorName":"Joe","managerName":"Nikolai","clientName":"Star Lord","goalName":"Save For Child Education","goalAmount":400000,"goals":1,"score":0.93,"lastModified":"","equityFixedIncome":"55/45"},{"id":"Client 8","advisorName":"Pal","managerName":"Rohan","clientName":"Thanos","goalName":"","goalAmount":"","goals":3,"score":0.29,"lastModified":"2/11/2019","equityFixedIncome":"","subRows":[{"id":"goal-10","clientName":"","managerName":"","advisorName":"","goalName":"Relocation Expense Goal","goalAmount":400000,"goals":1,"equityFixedIncome":"22/78","lastModified":"2/11/2019","score":0.29},{"id":"goal-11","clientName":"","managerName":"","advisorName":"","goalName":"Save for to buy bike","goalAmount":400000,"goals":1,"equityFixedIncome":"50/50","lastModified":"1/1/2020","score":0.29},{"id":"goal-12","clientName":"","managerName":"","advisorName":"","goalName":"Save For Education","goalAmount":400000,"goals":1,"equityFixedIncome":"65/35","lastModified":"9/5/2022","score":0.29}]},{"id":"Client 9","advisorName":"Pal","managerName":"Rohan","clientName":"Ego","goalName":"Save For Education","goalAmount":400000,"goals":1,"score":0.72,"lastModified":"","equityFixedIncome":"65/35"},{"id":"Client 10","advisorName":"Pal","managerName":"Rohan","clientName":"Bruce Banner","goalName":"","goalAmount":"","goals":2,"score":0.975,"lastModified":"9/10/2018","equityFixedIncome":"","subRows":[{"id":"goal-14","clientName":"","managerName":"","advisorName":"","goalName":"Car Loan","goalAmount":23000,"goals":1,"equityFixedIncome":"60/40","lastModified":"9/10/2018","score":0.99},{"id":"goal-15","clientName":"","managerName":"","advisorName":"","goalName":"Bike Loan","goalAmount":4600,"goals":1,"equityFixedIncome":"30/70","lastModified":"9/11/2021","score":0.96}]}]
function firstLevelManagerGroup(data){
return data.reduce(
(acc, row) => {
if (row.advisorName !== acc.level1.clientName) {
let newRow1 = {
advisorName: row.advisorName,
managerName: row.managerName,
id: "",
clientName: "",
goalName: "",
goalAmount: "",
goals: "",
score: "",
lastModified: "",
equityFixedIncome: "",
subRows: [],
};
acc.result.push(newRow1);
acc.level1.clientName = row.advisorName;
acc.level1.arr = newRow1.subRows;
}
let newRow2 = {
advisorName: "",
managerName: "",
id: row.id,
clientName: row.clientName,
goalName: row.goalName,
goalAmount: row.goalAmount,
goals: row.goals,
score: row.score,
lastModified: row.lastModified,
equityFixedIncome: row.equityFixedIncome,
};
if(row.subRows) {
acc.level2.arr = newRow2.subRows = [];
}
acc.level1.arr.push(newRow2);
if (row.subRows) {
row.subRows.forEach((subRow) => {
acc.level2.arr.push({ ...subRow });
});
}
return acc;
},
{
result: [],
level1: { clientName: "", arr: null },
level2: { arr: null },
}
).result;
}
const groupManager = (data, keyName) => {
let val = firstLevelManagerGroup(data)
const emptyNode = {
managerName: "",
advisorName: "",
id: "",
clientName: "",
goalName: "",
goalAmount: "",
goals: "",
score: "",
lastModified: "",
equityFixedIncome: "",
subRows: [],
};
const groups = val.reduce((acc, item) => {
acc[item[keyName]] ??= [];
acc[item[keyName]].push({ ...item, [keyName]: "" });
return acc;
}, {});
return Object.entries(groups)
.map(([keyValue, subRows]) => (
{ ...emptyNode, [keyName]: keyValue , subRows }
));
};
console.log(JSON.stringify(groupManager(data, 'managerName')));
CodePudding user response:
I just tweaked the code a little bit
const data = [{"id":"Client 1","mName":"SDk","cName":"Thor Odin","gName":"","gAmt":80000,"gls":2,"value":0.855,"date":"22/1/2022","income":"","subRows":[{"id":"goal-1","cName":"","mName":"","gName":"Retirement1","gAmt":10000,"gls":1,"income":"60/40","date":"22/1/2022","value":0.99},{"id":"goal-2","cName":"","mName":"","gName":"Save For Child Education","gAmt":70000,"gls":1,"income":"55/45","date":"5/12/2023","value":0.72}]},{"id":"Client 2","mName":"SDk","cName":"Steve Rogers","gName":"Save for Investment","gAmt":67000,"gls":1,"value":0.7,"date":"22/1/2022","income":"60/40"},{"id":"Client 3","mName":"Pal","cName":"Wanda Vision","gls":0,"value":0.9,"date":"","income":""},{"id":"Client 4","mName":"Pal","cName":"Tony Stark","gName":"","gAmt":23500,"gls":2,"value":0.29,"date":"27/10/2019","income":"","subRows":[{"id":"goal-4","cName":"","mName":"","gName":"Education Loan","gAmt":500,"gls":1,"income":"60/40","date":"27/10/2019","value":0.29},{"id":"goal-5","cName":"","mName":"","gName":"House Loan","gAmt":23000,"gls":1,"income":"30/70","date":"16/6/2022","value":0.29}]},{"id":"Client 5","mName":"Joe","cName":"Hack Eye","gName":"Save For World Tour","gAmt":400000,"gls":1,"value":0.74,"date":"","income":"60/40"},{"id":"Client 6","mName":"Joe","cName":"Nick Fury","gName":"","gAmt":51070,"gls":2,"value":0.44499999999999995,"date":"9/3/2022","income":"","subRows":[{"id":"goal-7","cName":"","mName":"","gName":"To Build A Workspace","gAmt":42340,"gls":1,"income":"60/40","date":"9/3/2022","value":0.6},{"id":"goal-8","cName":"","mName":"","gName":"Cloud Examination","gAmt":8730,"gls":1,"income":"30/70","date":"9/11/2021","value":0.29}]}];
const restucture = (data, keyName = 'mName') => {
const emptyNode = {
mName: "",
id: "",
cName: "",
gName: "",
gAmt: "",
gls: "",
value: "",
date: "",
income: "",
subRows: [],
};
const groups = data.reduce((acc, item) => {
acc[item[keyName]] ??= [];
acc[item[keyName]].push({ ...item, [keyName]: "" });
return acc;
}, {});
return Object.entries(groups)
.map(([keyValue, subRows]) => (
{ ...emptyNode, [keyName]: keyValue , subRows }
));
};
console.log(restucture(data, 'cName'));
.as-console-wrapper { max-height: 100% !important; top: 0 }