Search code examples
javascriptjsonreformat

Restructuring a JSON file in javascript


I have a JSON called 'from' that I want to convert to 'to' as follows. What is the fastest and most efficient way to achieve it? Is it possible to do in one step or should I reduce the duplicates first?:

  const from =[{ 
    NUM: '1234001',
    SUBNUM: '001'},
  { 
    NUM: '1234001',
    SUBNUM: '001'},
  { 
    NUM: '1234002',
    SUBNUM: '002'},
  { 
    NUM: '1234005',
    SUBNUM: '005'},
  { 
    NUM: '4567001',
    SUBNUM: '001'},
  { 
    NUM: '9999001',
    SUBNUM: '001'}
];


const to = [{
  label: 'SUBNUM',
  submenu: [{
    label: '1234',
    role: '1234',
       submenu: [{
         label: '001',
         role: '001'
       },
       {
         label: '002',
         role: '002'
       },
       {
         label: '005',
         role: '005'
       }]
    },{
    label: '4567',
    role: '4567',
       submenu: [{
         label: '001',
         role: '001'
       }]
    },{
    label: '9999',
    role: '9999',
       submenu: [{
         label: '001',
         role: '001'
       }]
  }
  ]}];

Solution

  • You can try following code:

    let items = [];
    
    from.forEach(obj => {
        let numTruncated = obj.NUM.replace(obj.SUBNUM, "");
        let currentNum = items.find(n => n.label === numTruncated);
        if(!currentNum ) {
            currentNum = {
                label: numTruncated,
                role: numTruncated,
                submenu: []
            };
            items.push(currentNum );
        }
    
        if(!currentNum .submenu.find(item => item.label === obj.SUBNUM)){
            currentNum .submenu.push({ label: obj.SUBNUM, role: obj.SUBNUM });
        }
    
    });
    
    let output = { label: "SUBNUM", submenu: items };
    

    find returns undefined if there's no element matching specified arrow function, using replace from string prototype to get rid of SUBNUM