Search code examples
javascriptangularlodash

Get all Keys/Array keys in JSON parse Object?


I have sample JSON like this

`{
  values:[{
    "name": "Base Url",
    "url": "https://kubemanagement-prod.kohls.com"
  },
  {
    "name": "Base Url newwww",
    "url": "https://batman.com"
  }]
}`

Currently when I add this paticular JSON to the lodash _.keys gives me the result ["0", "1"] which is basically the index of first and second object 0 and 1.

What I exactly want is to retrieve all the keys of the JSON object including sub object properties as well. In this case ["values","0", "1","name","url"]

Does anyone knows a lodash method or a mechanism to retrieve all the keys given in complex JSON object to nth level?

language : Angular + Typescript


Solution

  • This function recursively gets the keys from an objects tree, using _.keys() and _.flatMap() and _.union() to combine lists of keys, and get only the unique values:

    const getAllKeys = obj => _.union(
      _.keys(obj),
      _.flatMap(obj, o => _.isObject(o) ? getAllKeys(o) : [])
    )
    
    const arr = {"values": [{"name":"Base Url","url":"https://kubemanagement-prod.kohls.com"},{"name":"Base Url newwww","url":"https://batman.com"}]}
    
    const result = getAllKeys(arr)
    
    console.log(result)
    <script src="https://cdnjs.cloudflare.com/ajax/libs/lodash.js/4.17.11/lodash.js"></script>

    And the same idea without lodash, using Object.values() and Array.flatMap() to iterate the current object (or array), and Array.concat() and a Set to make the keys unique:

    const getAllKeys = obj => [...new Set([].concat(
      Object.keys(obj),
      Object.values(obj).flatMap(o => typeof o === 'object' ? getAllKeys(o) : [])
    ))]
    
    const arr = {"values": [{"name":"Base Url","url":"https://kubemanagement-prod.kohls.com"},{"name":"Base Url newwww","url":"https://batman.com"}]}
    
    const result = getAllKeys(arr)
    
    console.log(result)
    <script src="https://cdnjs.cloudflare.com/ajax/libs/lodash.js/4.17.11/lodash.js"></script>

    Without array indexes:

    const getAllKeys = obj => _.union(
      _.isArray(obj) ? [] : _.keys(obj),
      _.flatMap(obj, o => _.isObject(o) ? getAllKeys(o) : [])
    )
    
    const arr = {"values": [{"name":"Base Url","url":"https://kubemanagement-prod.kohls.com"},{"name":"Base Url newwww","url":"https://batman.com"}]}
    
    const result = getAllKeys(arr)
    
    console.log(result)
    <script src="https://cdnjs.cloudflare.com/ajax/libs/lodash.js/4.17.11/lodash.js"></script>