Home > Net >  Normalise the JSON where Array as an value in javascript
Normalise the JSON where Array as an value in javascript

Time:02-20

I was trying to normalize a very deeply nested JSON which contains all possible ways JSON can be created. A part of JSON can be seen in below code snippet.

What is my end goal

I am converting the nested JSON into a simple JS object like below

{
  key1: value,
  key2: value,
  ...
}

Problem i faced with the below solution is that when it comes to Objects with values as array i failed to find a way to see its key values.

if you run below code
key4,key5, key6 wont get displayed with the console.log only its value gets printed.

key1 -- values
key2 -- values
key3 -- value3
0 -- 
0 -- some_value

Code snippet

const req = {
      request: {
        results: {
          key1: 'values',
          results: [
            {
              key2: 'values',
            },
          ],
        },
        params: {
          key3: 'value3',
          query: {
            key4: [''],
            key5: ['123456'],
            key6: ['some_value'],
          },
        },
      },
    };
    
function normaliseJSON(obj) {
  for (let k in obj) {
    if (obj[k] instanceof Object) {
      normaliseJSON(obj[k]);
    } else {
      console.log(`${k} -- ${obj[k]}`);
    }
  }
}

normaliseJSON(req);

Is there any way to get the keys of key4,5,6 ? also open to any other solution to normalise such JSON

CodePudding user response:

  1. The reason your recursion goes inside the array is since ['123456'] instanceof Object is true in javascript (typeof(['asd']) also gives "object"). To check if something is an array have to check with Array.isArray(something)
  2. In template literals when you try to embed an array eg ...${['123456']} in the end it will show as ...123456 without the brackets. Therefore in situation of Arrays need to JSON.stringify(arr)

There may be better ways of doing this but I created a function called arrayHasObject which checks if an array has object elements. This was to catch the inner results array and ignore key4,key5 and key6.
The recursion will happen if obj[k] is an object and not an array or if obj[k] is an array and it has an object element.

Since recursion is hard to visualize I recommend https://pythontutor.com/ . It is mostly for Python but works for JS as well. It can help you visualize these things and to find where things go wrong

Ofcourse the way I have written it will break if something like key4: [{a:'abc'}] since arrayHasObject gives true for this. Maybe will need to change the function accordingly.

function arrayHasObject(arr) {
    return arr.some((x) => typeof(x)==='object' && !Array.isArray(x))
}


const req = {
      request: {
        results: {
          key1: 'values',
          results: [
            {
              key2: 'values',
            },
          ],
        },
        params: {
          key3: 'value3',
          query: {
            key4: [''],
            key5: ['123456'],
            key6: ['some_value'],
          },
        },
      },
    };
    
    
function normaliseJSON(obj) {
  for (let k in obj) {
    if ((obj[k] instanceof Object && !Array.isArray(obj[k])) || (Array.isArray(obj[k]) && arrayHasObject(obj[k]))) {
      normaliseJSON(obj[k]);
    } else {
        if (Array.isArray(obj[k])){
       console.log(`${k} -- ${JSON.stringify(obj[k])}`);
      }
      else{
       console.log(`${k} -- ${obj[k]}`);
      }
     
    }
  }
}

normaliseJSON(req);

  • Related