2

I am trying to write a javascript recursive function that receives one parameter - nested JSON object.

The function goes through the potentially infinitely nested object and converts all the keys (property names) to a string that is stored in array. Array is returned to a place where the function was called.

Example of JSON object:

{
  OBJECT1: {
    ATTRIBUTE3: {
      PARAMETER2: {
        PROPERTY1: {

        }
      }
    }
  }
}

The object does not hold any values.

What i tried and did not work:

function convertKeysToString(obj) {
  let keys = [];
  for (let key in obj) {
    if (typeof obj[key] === 'object') {
      keys = keys.concat(convertKeysToString(obj[key]));
    } else {
      keys.push(key.toString());
    }
  }
  return keys;
}

As a result, I expected that returned key is pushed to an array, but the funciton didnt get the key at all or was not pushed to keys array.

Another code I tried:

function getNestedObjectKeys(obj) {
  var keys = []
  var firstLevel = null

  var property = Object.keys(obj)
  property = property[0]
  firstLevel = Object.keys(obj[property])[0]
  if (firstLevel == undefined) {
    return 0
  }
  let returnedValue = keys.unshift(getNestedObjectKeys(obj[property]))

  if (returnedValue == 0) {
    return Object.keys(obj[property])[0]
  }
  returnedValue = Object.keys(obj[property])[0]
  if (returnedValue != obj[property[0]]) {
    return Object.keys(obj[property])[0]
  }
  else if (returnedValue == firstLevel) {
    return keys
  }
}

The function should return the key name and push (unshift) it to string and then return it, but the unshift doesnt do what I expect and in the returnedValue is not a expected returned string.

I approached it the way that the function findd the deepest (empty) object, and starts returning the name of the key. The thing is that I must return the key name AND push it to the string, which I can't find the way to accomplish at once.

Aurast
  • 3,189
  • 15
  • 24

2 Answers2

1

Your first solution is pretty close, but has one problem (well, one main problem): when the value is type object, you don't add its key to the array. So how is it supposed to get into the array? Give this a shot:

function convertKeysToString(obj) {
  let keys = [];
  for (let key in obj) {
    keys.push(key.toString());
    if (typeof obj[key] === 'object') {
      keys = keys.concat(convertKeysToString(obj[key]));
    }
  }
  return keys;
}

Other things you may want to consider:

  1. typeof null is object.
  2. typeof [] is also object.
Aurast
  • 3,189
  • 15
  • 24
  • 1
    Thank you so much! This worked like a miracle after spending more than 6 hours on this function. Does just what I expected. My approach was first check if it is an object and if so, check if it does contain any key or not (if it is empty). This approach was to get the key from the deepest level to the most shallow one, but your approach goes the other way. I mean, not realyl thanks to recursion, but you first get the current key and store it in a variable and THEN call the recursion. Much love to you. – Lukáš Schöbel Jan 14 '23 at 17:18
0

You could have a look to object, which are truthy and typeof object.

const
    getKeys = object => (keys => [
        ...keys.flatMap(key => object[key] && typeof object[key] === 'object'
            ? [key, ...getKeys(object[key])]
            : [key]
        )
    ])(Object.keys(object)),
    data = { OBJECT1: { ATTRIBUTE3: { PARAMETER2: { PROPERTY1: {} } } } },
    result = getKeys(data);

console.log(result);
Nina Scholz
  • 376,160
  • 25
  • 347
  • 392