Mehul
Mehul

Reputation: 178

How do I loop through a JSON object in MarkLogic to push all the keys in an array?

I have a multi level JSON like in the example below. I want to write a simple code to loop through it and fetch all the keys there are in it for validation purposes.

I tried Object.keys() but that gives the keys only for the first level of the object. How do I loop it to get the whole result?

{
"id": "0001",
"ppu": 0.55,
"batters": {
    "batter": [{
            "id": "1001",
            "type": "Regular"
        },
        {
            "id": "1004",
            "type": "Devil's Food"
        }
    ]
},
"topping": {
    "id": "5001",
    "type": "None",
    "moreData": {
        "id": "5003",
        "type1": "Chocolate",
        "type2": {
            "id": "5004",
            "type": "Maple"
        }
    }
  }
}

I normally get only the first keys, i.e. "id", "ppu","batters",topping" but I want all the keys including "batter", "type", "moreData", etc. NOTE: All my keys are unique unlike the example below.

EDIT - Code that I'm trying:

function keyCheck(obj) {
    var a = Object.keys(obj);
    var arr=[];
    arr.push(a);
    for (var i = 0; i < a.length; i++) {
        var b = obj[a[i]];
        if (typeof (b) == 'object') {
            keyCheck(b);
        }   
    }    
    return arr[0];
}
keyCheck(obj);

Upvotes: 0

Views: 490

Answers (5)

Mehul
Mehul

Reputation: 178

So I figured out a solution by using the inputs provided by everyone here.Due to some policy I cannot post my own solution but this is what I did: Get Object.keys() for first level data. Check if it's another object or array & call the same function recursively. If not then add it to the array.

Upvotes: 0

Slai
Slai

Reputation: 22876

The JSON.parse reviver parameter can be used to get all key value pairs :

var keys = {}, json = '{"id":"0001","ppu":0.55,"batters":{"batter":[{"id":"1001","type":"Regular"},{"id":"1004","type":"Devil\'s Food"}]},"topping":{"id":"5001","type":"None","moreData":{"id":"5003","type1":"Chocolate","type2":{"id":"5004","type":"Maple"}}}}'

JSON.parse(json, function(key, value) { if ( isNaN(key) ) keys[key] = value })

console.log( Object.keys(keys) )

Upvotes: 0

Neel Rathod
Neel Rathod

Reputation: 2111

You can achieve this with making a recursive function with Object.keys()

    const object = {
      id: '0001',
      ppu: 0.55,
      batters: {
        batter: [{
          id: '1001',
          type: 'Regular',
        },
        {
          id: '1004',
          type: "Devil's Food",
        },
        ],
      },
      topping: {
        id: '5001',
        type: 'None',
        moreData: {
          id: '5003',
          type1: 'Chocolate',
          type2: {
            id: '5004',
            type: 'Maple',
          },
        },
      },
    };
    
    
    function getKeyNames(obj, secondObj) {
      Object.keys(obj).forEach((r) => {
        const elem = obj[r];
        const refObj = secondObj;
        if (!Array.isArray(elem)) {
          refObj[r] = r;
        }
        if (typeof elem === 'object' && (!Array.isArray(elem))) {
          getKeyNames(elem, secondObj);
        }
      });
      return secondObj;
    }
    
    function getAllKeys(obj) {
      const secondObj = {};
      const keys = getKeyNames(obj, secondObj);
      return Object.keys(keys);
    }
    
    const result = getAllKeys(object);
    console.log(result);

Upvotes: 1

arizafar
arizafar

Reputation: 3122

You can write a recursive method as follows,

let obj = {
	"id": "0001",
	"ppu": 0.55,
	"batters": {
		"batter": [{
			"id": "1001",
			"type": "Regular"
		},
		{
			"id": "1004",
			"type": "Devil's Food"
		}
		]
	},
	"topping": {
		"id": "5001",
		"type": "None",
		"moreData": {
			"id": "5003",
			"type1": "Chocolate",
			"type2": {
				"id": "5004",
				"type": "Maple"
			}
		}
	}
}

function getKeys(obj, arr = []) {
	Object.entries(obj).forEach(([key, value]) => {
		if(typeof value === 'object' && !Array.isArray(value)) {
			arr.push(key);
			getKeys(value, arr);
		} else {
			arr.push(key);
		}
	});
	return arr;
}

console.log(getKeys(obj));

For old browsers

function getKeys(obj, arr = []) {
    Object.entries(obj).forEach(function(entry) {
        let key = entry[0];
        let value = entry[1]
        if(typeof value === 'object' && !Array.isArray(value)) {
            arr.push(key);
            getKeys(value, arr);
        } else {
            arr.push(key);
        }
    });
    return arr;
}

Upvotes: 1

baao
baao

Reputation: 73251

You can use a recursive function to get all the keys. Below method takes a second argument unique that lets you set if keys should be duplicated in your resulting array of keys.

const allKeys = (obj, unique = true) => {
  const res = Object.entries(obj).flatMap(([k, v]) => {
    if (typeof v === 'object') {
      if (Array.isArray(v)) return [k, v.flatMap(vv => allKeys(vv, unique))].flat();
      return [k, allKeys(v, unique)].flat();
    }
    return k;
  });
  return unique ? [...new Set(res)] : res;
};


console.log(allKeys(obj));
<script>
  const obj = {
    "id": "0001",
    "ppu": 0.55,
    "batters": {
      "batter": [{
          "id": "1001",
          "type": "Regular"
        },
        {
          "id": "1004",
          "type": "Devil's Food"
        }
      ]
    },
    "topping": {
      "id": "5001",
      "type": "None",
      "moreData": {
        "id": "5003",
        "type1": "Chocolate",
        "type2": {
          "id": "5004",
          "type": "Maple"
        }
      }
    }
  };
</script>

Upvotes: 0

Related Questions