0

Hi I am having an array of objects like this

[
    {
      "managerName":  "Ramani",
      "name": "Suresh",
      "goalName": "",
      "subRows": [
        {
          "managerName":  "",
          "name": "",
          "goalName": "Retirement1"
        },
        {
          "managerName":  "",
          "name": "",
          "goalName": "Save For Child Education"
        }
      ]
    },
    {
      "managerName":  "Ramani",
      "name": "Lakshmi",
      "goalName": "Save for Investment"
    },
    {
        "managerName":  "Kamal",
        "name": "John",
        "goalName": "",
        "subRows": [
          {
            "managerName":  "",
            "name": "",
            "goalName": "Loan Repayment"
          },
          {
            "managerName":  "",
            "name": "",
            "goalName": "Car Loan"
          }
        ]
      }
]

is it possible to convert the above data into a format like this below? Here in the below data you can see that the data is structured based on the manager's name.

e.g Ramani (Manager) has repeated two objects. So the data is combined into subRows and the manager name is created as a key at the top.

Expected Data Format

[
    {
      "managerName": "Ramani",
      "name": "",
      "goalName": "",
      "subRows": [
        {
          "managerName": "",
          "name": "Suresh",
          "goalName": "",
          "subRows": [
            {
              "managerName": "",
              "name": "",
              "goalName": "Retirement1"
            },
            {
              "managerName": "",
              "name": "",
              "goalName": "Save For Child Education"
            }
          ]
        },
        {
          "managerName": "",
          "name": "Lakshmi",
          "goalName": "Save for Investment"
        }
      ]
    },
    {
      "managerName": "Kamal",
      "name": "",
      "goalName": "",
      "subRows": [
        {
          "managerName": "",
          "name": "John",
          "goalName": "",
          "subRows": [
            {
              "managerName": "",
              "name": "",
              "goalName": "Loan Repayment"
            },
            {
              "managerName": "",
              "name": "",
              "goalName": "Car Loan"
            }
          ]
        }
      ]
    }
  ]

Why I am doing this because I am creating a table using @tanstack/react-table with multi-level nested expansion. For that table to support that expansion it requires the data needs to be formatted like the one in the above. You can see the working demo of the table in this link - https://codesandbox.io/s/tanstack-table-expansion-sub-level-poryuv?file=/src/App.js

And please let me know If it's possible to frame the data ( expected format ) from the data ( provided at the top )? If that's possible could you help me with the solution

var data=[
    {
        "managerName":"kumar",
        "name": "dhanush",
        "goals": ["goal 1","goal 2"]
    },
    {
        "managerName":"Test",
        "name": "kumar",
        "goals": ["goal 3", "goal 4"]
    },
    {
        "managerName":"lorem",
        "name": "test",
        "goals": ["goal 5"]
    }
]

const result = data.map(({ managerName,name, goals, goalAmount }) => {
  return goals.length === 1
    ? { managerName,name, goals: goals[0]}
    : {
        managerName,
        name,
        goals: '',
        subRows: goals.map(
          (goal, i) => ({ managerName:'',name: '', goal })
        )
    };
});

console.log(result)


Here I converted the API returned data to the first data format. Using the above-defined function but not able to convert to the desired output.

Simplified Question

Given Data

[
    {
        "group_id": 1,
        "name":"Dhanush",
        "age":27
    },
    {
        "group_id": 1,
        "name":"Dharma",
        "age":24
    },
    {
        "group_id": 2,
        "name":"Lorem",
        "age":23
    }
]

Output

[
    {
        "group_id":1,
        "details":[
            {
                "name":"Dhanush",
                "age": 27
            },
            {
                "name":"Dharma",
                "age": 24
            }
        ]
    },
    {
        "group_id": 2,
        "details": [
            {
                "name":"Lorem",
                "age":23
            }
        ]
    }
]

SDK
  • 1,356
  • 3
  • 19
  • 44
  • 2
    What have you tried so far to solve this on your own? What are the problems with that approach? -> [How much research effort is expected of Stack Overflow users?](https://meta.stackoverflow.com/questions/261592/how-much-research-effort-is-expected-of-stack-overflow-users) – Andreas Jul 24 '22 at 16:27
  • Sorry, now I added my solution – SDK Jul 24 '22 at 16:33
  • The version that works is not relevant for the question... What have you tried so far to solve the actual question/problem (how to get the expected output format) – Andreas Jul 24 '22 at 16:40
  • The _"Simplified Question"_ is just a dump of in- and expected output... – Andreas Jul 24 '22 at 17:03
  • Does this answer your question? [How can I group an array of objects by key?](https://stackoverflow.com/questions/40774697/how-can-i-group-an-array-of-objects-by-key) – pilchard Jul 24 '22 at 17:18

1 Answers1

1

you can do that... with an array reduce:

const data = 
  [ { managerName: 'Ramani', name: 'Suresh',  goalName: '',                 subRows: 
      [ { managerName: '',   name: '',        goalName: 'Retirement1'              } 
      , { managerName: '',   name: '',        goalName: 'Save For Child Education' } 
    ] } 
  , { managerName: 'Ramani', name: 'Lakshmi', goalName: 'Save for Investment'      } 
  , { managerName: 'Kamal',  name: 'John',    goalName: '',                 subRows: 
      [ { managerName: '',   name: '',        goalName: 'Loan Repayment'           } 
      , { managerName: '',   name: '',        goalName: 'Car Loan'                 } 
  ] } ] 

const arrExpected = data.reduce((acc,row) =>
  {
  if (row.managerName !== acc.level1.name)
    {
    let newRow1 =  { managerName: row.managerName,  name: '', goalName: '', subRows:[] }
    acc.result.push( newRow1 )
    acc.level1.name = row.managerName
    acc.level1.arr  = newRow1.subRows
    }
  let newRow2 = { managerName: '',  name: row.name, goalName: row.goalName }

  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:{name:'',arr:null}, level2:{arr:null}} 
  ).result;


console.log( arrExpected  )
.as-console-wrapper {max-height: 100% !important;top: 0;}
.as-console-row::after {display: none !important;}

Formated result :

[ { managerName: 'Ramani',   name: '',        goalName: '',                 subRows: 
    [ { managerName: '',     name: 'Suresh',  goalName: '',                 subRows: 
        [ { managerName: '', name: '',        goalName: 'Retirement1'              } 
        , { managerName: '', name: '',        goalName: 'Save For Child Education' } 
      ] } 
    , { managerName: '',     name: 'Lakshmi', goalName: 'Save for Investment'      } 
    ] } 
, { managerName: 'Kamal',    name: '',        goalName: '',                 subRows: 
    [ { managerName: '',     name: 'John',    goalName: '',                 subRows: 
        [ { managerName: '', name: '',        goalName: 'Loan Repayment'           } 
        , { managerName: '', name: '',        goalName: 'Car Loan'                 } 
] } ] } ] 
Mister Jojo
  • 20,093
  • 6
  • 21
  • 40