Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Nested recursive array loop

Was wondering if anyone knows of a way to use lodash, or vanilla JS to achieve this small problem?

I have this starting object:

{
  "1": {
    "null": {
      "2": {
        "3": {
          "6": {
            "7": "c"
          },
          "null": {
            "null": {
              "5": "b"
            }
          }
        }
      }
    }
  },
  "8": {
    "10": "e",
    "null": {
      "9": "d"
    }
  }
}

Each level (horizontally) means something. So level 1 is of type A, level 2 is of type B, 3 of type A, 4 of type B and so forth. So it alternates.

Is there a nice and simply way to "collapse" this object to look something like this:

[
  {
    "type": "A",
    "label": "1",
    "children": [
      {
        "type": "A",
        "label": "2",
        "children": [
          {
            "type": "B",
            "label": "3",
            "children": [
              {
                "type": "A",
                "label": "6",
                "children": [
                  {
                    "type": "A",
                    "label": "7",
                    "value": "c"
                  }
                ]
              },
              {
                "type": "A",
                "label": "8",
                "children": [
                  {
                    "type": "A",
                    "label": "5",
                    "value": "b"
                  }
                ]
              }
            ]
          }
        ]
      }
    ]
  },
  {
    "type": "A",
    "label": "8",
    "children": [
      {
        "type": "B",
        "label": "10",
        "value": "e"
      },
      {
        "type": "A",
        "label": "9",
        "value": "d"
      }
    ]
  }
]

In essence annotating each level with what type it is, and nesting its children.

like image 973
Marais Rossouw Avatar asked May 21 '26 00:05

Marais Rossouw


1 Answers

Here is the code

function transformObj(obj, level) {
  level = level || 1;
  var result = _(obj).transform(function(result, value, key) {
    var obj = {
      type: (level % 2 === 0) ? 'B' : 'A',
      label: key
    };
    if (key === 'null') {
      result.push(transformObj(value, level+1));
    } else {
      if (_.isObject(value)) {
        obj.children = transformObj(value, level+1);
      } else {
        obj.value = value;
      }
      result.push(obj);
    }
  }, [])
  .flatten()
  .value();
  return result;
}

Here is the output

[
    {
        "type": "A",
        "label": "1",
        "children": [
            {
                "type": "A",
                "label": "2",
                "children": [
                    {
                        "type": "B",
                        "label": "3",
                        "children": [
                            {
                                "type": "A",
                                "label": "6",
                                "children": [
                                    {
                                        "type": "B",
                                        "label": "7",
                                        "value": "c"
                                    }
                                ]
                            },
                            {
                                "type": "A",
                                "label": "5",
                                "value": "b"
                            }
                        ]
                    }
                ]
            }
        ]
    },
    {
        "type": "A",
        "label": "8",
        "children": [
            {
                "type": "B",
                "label": "10",
                "value": "e"
            },
            {
                "type": "A",
                "label": "9",
                "value": "d"
            }
        ]
    }
]
like image 121
satish Avatar answered May 22 '26 13:05

satish