Home > Mobile >  How to restructure array of objects to a nested array of object in JS?
How to restructure array of objects to a nested array of object in JS?

Time:07-28

I am having an array like this

[
  {
    "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
          }
        ]
      }
    ]
  }
]

grouping the array using mName. This below function is working fine on converting the provided array of objects.


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":"SDk","cName":"Wanda Vision","gls":0,"value":0.9,"date":"","income":""},{"id":"Client 4","mName":"SDk","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}]},{"id":"Client 7","mName":"Joe","cName":"Star Lord","gName":"Save For Child Education","gAmt":400000,"gls":1,"value":0.93,"date":"","income":"55/45"},{"id":"Client 8","mName":"Pal","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}]},{"id":"Client 9","mName":"Pal","cName":"Ego","gName":"Save For Education","gAmt":400000,"gls":1,"value":0.72,"date":"","income":"65/35"},{"id":"Client 10","mName":"Pal","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}]}]
  
  const arrExpected = data.reduce((acc,row) =>
    {
    if (row.mName !== acc.level1.cName)
      {
      let newRow1 =  { mName:row.mName, id: '',  cName: '', gName: '',gAmt:'',gls:'',value:'',date:'',income:'', subRows:[] }
      acc.result.push( newRow1 )
      acc.level1.cName = row.mName
      acc.level1.arr  = newRow1.subRows
      }
    let newRow2 = { mName: '',id: row.id,  cName: row.cName, gName: row.gName, gAmt: row.gAmt, gls: row.gls, value:row.value, date: row.date, income: row.income}
  
    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:{cName:'',arr:null}, level2:{arr:null}} 
    ).result;
  
  
 console.log(JSON.stringify(arrExpected) )

But the above function is quite complicated to understand. If a new person takes over the code means it's hard to know what it is doing.

Is any way this function can be simplified? Please let me know the feasibility of this one.

And why I am doing this kind of structure because. I am in creating a multi-level expandable table row using @tanstack/react-table. For that, It requires structure like this.

Here u can get the working demo example of this https://codesandbox.io/s/tanstack-table-expansion-sub-level-goe-191pip?file=/src/App.js

CodePudding user response:

To decrease amount of code and improve understanding, you can take the following approach

// const data = [ big array of objects ];

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 }));
  • Related