4
\$\begingroup\$

I have JSON data which can be an object/array of recursively nested object or array. The value of an array can not be null, but a value in an object can be null. And I would like to return all combinations of these keys and values through depth-first search.

For example:

var data = {
  "title": {
     "original": "Hitchhiker",
     "more": ["HGTTG"],
     "link": null
  },
  "date": ["20150101", "20160101"]
}

The data's length and depth is arbitrary, and the combination result I want is something like this:

["title-original-Hitchhiker", "title-more-HTTG", "title-link", "date-20150101", "date-20160101"]

What I came up with is recursive:

function nestedObjectToArray(obj) {
  if (typeof(obj) != "object"){
    return [obj];
  }
  var result = [];
  if (obj.constructor == Array){
    for (var i = 0; i <obj.length; i++){
      if (obj[i]){
        var temp = nestedObjectToArray(obj[i]);
        for (var j = 0; j < temp.length; j++){
          result.push(temp[j]);
        }
      }
    }
  } else {
    for (var i in obj){
      if (obj.hasOwnProperty(i)) {
        if (obj[i] == null){
          result.push(i);
        } else {
          var temp = nestedObjectToArray(obj[i]);
          for (var j = 0; j < temp.length; j++){
            result.push(i+"-"+temp[j]);
          }
        }
      }
    }
  }
  return result;
}

Would you have a better/more elegant solution than this chunk of conditions, loops and recursion? I can use any library if it's more convenient.

\$\endgroup\$

migrated from stackoverflow.com Apr 26 '16 at 18:11

This question came from our site for professional and enthusiast programmers.

1
\$\begingroup\$

A little refactor solution can be

function nestedObjectToArray(obj) {
    if (typeof(obj) !== "object"){
        return [obj];
    }
    var result = [];
    if (obj.constructor === Array){
        obj.map(function(item) {
            result = result.concat(nestedObjectToArray(item));
        });
    } else {
        Object.keys(obj).map(function(key) {
            if(obj[key]) {
                var chunk = nestedObjectToArray(obj[key]);
                chunk.map(function(item) {
                    result.push(key+"-"+item);
                });
            } else {
                result.push(key);
            }
        });
    }
    return result;
}
\$\endgroup\$
  • \$\begingroup\$ You have presented an alternative solution, but haven't reviewed the code. Please edit to show what aspects of the question code prompted you to write this version, and in what ways it's an improvement over the original. It may be worth (re-)reading How to Answer. \$\endgroup\$ – Toby Speight Apr 2 at 16:46
  • \$\begingroup\$ Note that this answer was migrated from StackOverflow. \$\endgroup\$ – rolfl Apr 2 at 19:21

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service, privacy policy and cookie policy

Not the answer you're looking for? Browse other questions tagged or ask your own question.