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\$
0

1 Answer 1

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\$
2
  • \$\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\$ Apr 2, 2019 at 16:46
  • \$\begingroup\$ Note that this answer was migrated from StackOverflow. \$\endgroup\$
    – rolfl
    Apr 2, 2019 at 19:21

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge that you have read and understand our privacy policy and code of conduct.

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