1
\$\begingroup\$

Upon suggestion in the original question within Stack Overflow, I'm bringing my question here.

We have created a function that will convert the data into the desired format, but it has a lot of code and is difficult to understand. If a new person has seen this code means, it's very hard for them to know the functionalities.

below is the code for it

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 firstLevelRestructure(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 restructure = (data, keyName) => {
 let val = firstLevelRestructure(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(restructure(data, 'managerName')));

And why am doing this conversion because, we are creating a multi level nested row expansion table which requires this kind of structure. You can get the working demo link here - https://codesandbox.io/s/tanstack-table-expansion-1t77ks?file=/src/styles.css

enter image description here

And the structured data will be used to create the table with the expansion like in the above image.

Here u can see the formatted data - https://codesandbox.io/s/tanstack-table-expansion-1t77ks?file=/src/data/table-data.json

Instead of calling the function firstLevelRestructure Is there a way to use the function restructure to handle it?

I am in need of your help to solve this. Please let me know the feasibility of that.

pacmaninbw
26.2k13 gold badges47 silver badges113 bronze badges
asked Jul 29, 2022 at 0:13
\$\endgroup\$
2
  • 4
    \$\begingroup\$ I have rolled back Rev 7 → 5. Please see What to do when someone answers. \$\endgroup\$ Commented Jul 30, 2022 at 14:01
  • \$\begingroup\$ As the moderator @SᴀᴍOnᴇᴌᴀ indicated yesterday please do not edit the question, especially the code, after an answer has been posted. Changing the question may cause answer invalidation. Everyone needs to be able to see what the reviewer was referring to. What to do after the question has been answered. \$\endgroup\$ Commented Aug 1, 2022 at 12:01

2 Answers 2

3
\$\begingroup\$

I think you should work on the spirit of information synthesis, it should help you get a simpler way of coding

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}]}]
const
 nodOrder = 
 { managerName: '', advisorName: '', clientName: '', id: ''
 , goalName: '' , goalAmount: '', goals: '', score: ''
 , lastModified: '', equityFixedIncome: ''
 } 
, levels = 
 { managerName: { arr: null, val: '' }
 , advisorName: { arr: null, val: '' }
 , clientName: { arr: null }
 }
, ResultData = []
 ;
data.forEach( ({ managerName, advisorName, ...otherProps }) => 
 {
 let
 row_0 = Object.assign({}, nodOrder, { managerName })
 , row_1 = Object.assign({}, nodOrder, { advisorName })
 , row_2 = Object.assign({}, nodOrder, otherProps )
 ;
 if (levels.managerName.val !== managerName )
 {
 levels.managerName.val = managerName 
 levels.managerName.arr = row_0.subRows = []
 levels.advisorName.val = ''
 ResultData.push( row_0 )
 }
 if (levels.advisorName.val !== advisorName )
 {
 levels.advisorName.val = advisorName 
 levels.advisorName.arr = row_1.subRows = []
 levels.managerName.arr.push( row_1 )
 }
 levels.clientName.arr = (otherProps.subRows) ? (row_2.subRows = []) : null
 levels.advisorName.arr.push( row_2 )
 if (otherProps.subRows) 
 {
 otherProps.subRows.forEach( subRow => 
 {
 let sRow = Object.assign({}, nodOrder, subRow )
 levels.clientName.arr.push( sRow )
 })
 }
 })
console.log( ResultData ) 
.as-console-wrapper {max-height: 100% !important;top: 0;}
.as-console-row::after {display: none !important;}

answered Jul 30, 2022 at 12:42
\$\endgroup\$
1
  • \$\begingroup\$ Nice reorganization. In retrospect, renaming for meaningful variables (my pet peeve) at the same time would make the code restructuring itself harder to appreciate. \$\endgroup\$ Commented Jul 30, 2022 at 18:25
3
\$\begingroup\$

it has a lot of code and is difficult to understand

  1. What business entities, or DB tables perhaps, do "row" and "subrow" represent?

  2. The objects are shredded down to their properties and put into two different objects of exactly the same schema as the object they were ripped from.

  3. What is "acc"? It is the transformed data objects I guess, so what it that?

  4. Names "newrow1" and "newrow2" and "row" suggest these are all the same kind of thing - the same business entity; the same DB table object; the same Class; because they are all "rows" - like identical twins having identical DNA (object definition/structure) each with half of the other's own data.

What is the data schema?

Name variables/objects for the business entities they represent.

That "row" data is ripped in half into "newrow1" and "newrow2" hints to me that they should be different classes/objects with only the properties appropriate to each.

Code to reflect data structure

I have no idea what an arr is but I think [ ] and { } is less error prone than null - and is more consistent with initialization in other parts of the code. And no need to test for null before iterating, adding to, etc.

In my opinion the code is too clever by using reduce. It obscures the data structure and transformations. I generally prefer separate methods for building parts of the data structure. That will clearly show the data structure and data relations.

"Methods/functions will be too small", not worth the effort you might say. Try it and see if it doesn't meet your goal: If a new person has seen this code means, it's very (削除) hard (削除ここまで) easy for them to know the functionalities.

answered Jul 29, 2022 at 23:19
\$\endgroup\$
1
  • \$\begingroup\$ Hi, Thanks for the info. I agree that my question has a lot of grey areas that are difficult to understand. Am working on that to explain the details furthermore. \$\endgroup\$ Commented Jul 30, 2022 at 13:44

Your Answer

Draft saved
Draft discarded

Sign up or log in

Sign up using Google
Sign up using Email and Password

Post as a guest

Required, but never shown

Post as a guest

Required, but never shown

By clicking "Post Your Answer", you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.