0

EDIT: Updated JSfiddle

I need to loop over a JSON array without knowing the depth of each object or nested object.

The desired output should relate the main parent name and label into the last child name and parent. Check this table to understand more of what I want:

enter image description here

As you can see for France and USA, they are in 2 children nested arrays that's why they are like more_data/favourite_destination/USA and more_data/favourite_destination/France.

Sometimes I would have more than that, which means parent/child_1/child_2/..../child_name.

Notice as well that for the field label, I only need the last label of question.

The behaviour of the JSON is that we never knows when the label is simple label: label_value or when it is wrapped into an object like:

"label": {
     "english": "some text"
}

Here is my script:

function recursiveTree(data, p_dim_name, p_dim_label, p_field_name, p_field_label) {
  for (parent_key in data) {
      var dim_name = "";
      var dim_label = "";
      var field_name = "";
      var field_label = "";
      
      dim_name = p_dim_name == "" ? data[parent_key]["name"] : data[parent_key]["name"]+"/"+p_dim_name;
      field_name = p_field_name == "" ? data[parent_key]["name"] : data[parent_key]["name"]+"/"+p_dim_name+"/"+dim_name;

      if (typeof data[parent_key]["label"] === "object") {
        dim_label = p_dim_label == "" ? data[parent_key]["label"]["english"] : data[parent_key]["label"]["english"]+"/"+p_dim_label;
        field_label = p_field_label == "" ? data[parent_key]["label"]["english"] : p_dim_label;
      } else {
        dim_label = p_dim_label == "" ? data[parent_key]["label"] : data[parent_key]["label"]+"/"+p_dim_label;
        field_label = p_field_label == "" ? data[parent_key]["label"] : p_dim_label;
      }
      // field_label = p_field_label == "" ? data[parent_key]["label"] : data[parent_key]["label"]+"/"+p_dim_label+"/"+dim_label;
      //console.log(("children" in data[parent_key]))
      if (data[parent_key].children) {
        for (child_key in data[parent_key]["children"]) {
          //console.log(data[parent_key]["children"][child_key])
          //console.log(data[parent_key]["children"][child_key]);
          recursiveTree(data[parent_key]["children"], dim_name, dim_label, field_name, field_label);
        }
      }
      else {
        console.log(field_name);
        // console.log("FALSE")
      }

  }
}


recursiveTree(data["children"], "", "", "", "")

And here is a sample array, which might have in the real life json file lots of nodes and childs, but this is a simple one to test with:

    var data = {
    "name": "Info",
    "title": "Info",
    "default_language": "default",
    "id_string": "...",
    "type": "survey",
    "children": [
        {
            "type": "text",
            "name": "basic_info",
            "label": "Basic Info",
            "children": [
                {
                    "type": "text",
                    "name": "name",
                    "label": {
                        "english": "What is your name"
                    }
                },
                {
                    "type": "text",
                    "name": "address",
                    "label": {
                        "english": "What is your address?"
                    }
                }
            ]
        },
        {
            "type": "text",
            "name": "more_data",
            "label": "More Data",
            "children": [
                {
                    "type": "text",
                    "name": "favourite_food",
                    "label": {
                        "english": "What is your favourite food?"
                    }
                },
                {
                    "type": "text",
                    "name": "favourite_destination",
                    "label": {
                        "english": "What is your favourite destination?"
                    },
                    "children": [
                        {
                            "type": "text",
                            "name": "france",
                            "label": {
                                "english": "France"
                            }
                        },
                        {
                            "type": "text",
                            "name": "usa",
                            "label": {
                                "english": "USA"
                            }
                        }
                    ]
                }
            ]
        },
        {
            "type": "number",
            "name": "estimated_income",
            "label": "What is your annual estimated income?"
        }
    ]
}

My script is returning everything doubled and flipped, which means instead of returning: basic_info/name for field_name it is returning "name/basic_info/name/basic_info" and the same of the other fields.

Here is a jsfiddle describing the whole issue with the output.

alim1990
  • 4,656
  • 12
  • 67
  • 130

1 Answers1

0

I found my own solution. Here is the script:

var outputArray = [];
function recursiveTree(data, p_dim_name, p_dim_label, p_field_name, p_field_label) {
for (parent_key in data) {
    if(data[parent_key]["name"]!="meta" && data[parent_key]["type"]!="start" && data[parent_key]["type"]!="end" && data[parent_key]["type"]!="deviceid" && data[parent_key]["type"]!="today"){
    var dim_name = "";
    var dim_label = "";
    var field_name = "";
    var field_label = "";
    var field_type = "";
    dim_name = p_dim_name == "" ? data[parent_key]["name"] : p_dim_name;
    field_name = p_field_name == "" ? data[parent_key]["name"] : p_field_name+"/"+data[parent_key]["name"];
    field_type = data[parent_key]["type"] == undefined ? "select multiple" : data[parent_key]["type"];

    if (data[parent_key]["label"] && typeof data[parent_key]["label"] === "object") {
        dim_label = p_dim_label == "" ? data[parent_key]["label"]["english"] : p_dim_label+"/"+data[parent_key]["label"]["english"];
        field_label =  data[parent_key]["label"]["english"];
    } else if (data[parent_key]["label"] && typeof data[parent_key]["label"] != "object") {
        dim_label = p_dim_label == "" ? data[parent_key]["label"] : data[parent_key]["label"]+"/"+p_dim_label;
        field_label = data[parent_key]["label"] ;
    }
    else  {
        dim_label = dim_name;
    }
    var obj = {};
        obj = 
        {
            "dim_label": dim_label,
            "dim_name": field_name.slice(0, field_name.lastIndexOf("/")),
            "field_name": field_name,
            "field_label": field_label,
            "field_type": field_type
        };
    // field_label = p_field_label == "" ? data[parent_key]["label"] : data[parent_key]["label"]+"/"+p_dim_label+"/"+dim_label;
    //console.log(("children" in data[parent_key]))
    if (data[parent_key].children && data[parent_key].type != "select one") {
        recursiveTree(data[parent_key]["children"], dim_name, dim_label, field_name, field_label);
    }
    outputArray.push(obj)
    
    }
    
}
return outputArray;
}
  
var result = recursiveTree(data["children"], "", "", "", "");
console.log(result)
alim1990
  • 4,656
  • 12
  • 67
  • 130