Recursive javascript function that converts nested object keys to string and store all keys in arrray

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.

Upvotes: 2

Views: 1060

Answers (2)

Nina Scholz
Nina Scholz

Reputation: 386816

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);

Upvotes: 0

Aurast
Aurast

Reputation: 3688

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.

Upvotes: 1

Related Questions