Mrityunjay Yadav
Mrityunjay Yadav

Reputation: 11

How to add item to each level of a nested array

I have an array with infinite levels in each object and want to add an id field based on the level. For level 1 the ID should be 1, for level two the ID should be 2, etc.

{
    "name": "Anything2",
    "code": "SS_1",
    "levels": [
        {
            "levelName": "New level",
            "levels": [
                {
                    "levelName": "New Level2",
                    "levels": [
                        {
                            "levelName": "New Level2",
                            {
                                "levelName": "New Level2",
                                "levels": [
                                    {
                                        "levelName": "New level"
                                    }
                                ]
                            }
                        },
                        {
                            "levelName": "New Level2",
                        },
                        {
                            "levelName": "New Level2",
                        }
                    ]
                },
                {
                    "levelName": "New Level2"
                },
                {
                    "levelName": "New Level2",
                    "levels": [
                        {
                            "levelName": "New level"
                        }
                    ]
                }
            ]
        }
    ]
}

I want to convert the above array into below new array. I have tried using a for loop, but it's not working. I am not getting the expected data.

{
    "name": "Anything2",
    "code": "SS_1",
    "levels": [
        {
            "level": 1,
            "levelName": "New level",
            "levels": [
                {
                    "level": 2,
                    "levelName": "New Level2",
                    "levels": [
                        {
                            "level": 3,
                            "levelName": "New Level2",
                            {
                                "levelName": "New Level2",
                                "levels": [
                                    {
                                        "level": 4,
                                        "levelName": "New level"
                                    }
                                ]
                            }
                        },
                        {
                            "level": 3,
                            "levelName": "New Level2",
                        },
                        {
                            "level": 3,
                            "levelName": "New Level2",
                        }
                    ]
                },
                {
                    "level": 2,
                    "levelName": "New Level2"
                },
                {
                    "level": 2,
                    "levelName": "New Level2",
                    "levels": [
                        {
                            "level": 3,
                            "levelName": "New level"
                        }
                    ]
                }
            ]
        }
    ]
}

Upvotes: 1

Views: 1332

Answers (4)

user6316468
user6316468

Reputation:

Here is a simple solution using a stack and a while loop.

var tree = {
  children: [{
    children: [{
      children: []
    }, {
      children: []
    }]
  }, {
    children: [{
      children: []
    }]
  }]
};

var stack = [
  [tree, 0] // `0` is the `i` below
];

var n; while (n = stack.length) {
  let [node, i] = stack[n - 1];
  if (i < node.children.length) {
    stack.push([node.children[i], 0]);
    stack[n - 1][1]++; // increment `i`
  } else {
    stack.pop();
    node.depth = n;
  }
}

console.log(tree);

Upvotes: 0

A1exandr Belan
A1exandr Belan

Reputation: 4780

Think it works:

const data = {"name": "Anything2","code": "SS_1","levels": [{"levelName": "New level","levels": [{"levelName": "New Level2","levels": [{"levelName": "New Level2","levels": [{"levelName": "New level"}]},{"levelName": "New Level2",},{"levelName": "New Level2",}]},{"levelName": "New Level2"},{"levelName": "New Level2","levels": [{"levelName": "New level"}]}]}]};
        

const iter = (arr, level) => 
  arr.map((obj) => 
    Array.isArray(obj.levels) 
      ? { level, ...obj,  levels: iter(obj.levels, level + 1) } 
      : { level, ...obj });

const result = {...data, levels: iter(data.levels, 1) };

console.dir(result,  {depth: null})
.as-console-wrapper{min-height: 100%!important; top: 0}

Upvotes: 0

Nina Scholz
Nina Scholz

Reputation: 386540

You could take a recursive approach and hand over an incremented level for each level.

addLevels takes a level variable and returns a nother function which separates levels from the object. The rest of the object is a new variable.

The inner function returns a new object with a level property, the old object without levels and a property levels which gets the mapping of the nested arrays.

addLevel features a closure over level which keeps the value for the nested function.

const
    addLevel = (level = 0) => ({ levels = [], ...o }) =>
        ({ level, ...o, levels: levels.map(addLevel(level + 1)) }),
    data = { name: "Anything2", code: "SS_1", levels: [{ levelName: "New level", levels: [{ levelName: "New Level2", levels: [{ levelName: "New Level2" }, { levelName: "New Level2", levels: [{ levelName: "New level" }] }, { levelName: "New Level2" }, { levelName: "New Level2" }] }, { levelName: "New Level2" }, { levelName: "New Level2", levels: [{ levelName: "New level" }] }] }] },
    result = addLevel()(data);

console.log(result);
.as-console-wrapper { max-height: 100% !important; top: 0; }

Upvotes: 1

chrwahl
chrwahl

Reputation: 13070

Here I call the property "depth":

const data = {
  "name": "Anything2",
  "code": "SS_1",
  "levels": [{
    "levelName": "New level",
    "levels": [{
        "levelName": "New Level2",
        "levels": [{
            "levelName": "New Level2"
          },
          {
            "levelName": "New Level2",
            "levels": [{
              "levelName": "New level"
            }]
          },
          {
            "levelName": "New Level2"
          },
          {
            "levelName": "New Level2"
          }
        ]
      },
      {
        "levelName": "New Level2"
      },
      {
        "levelName": "New Level2",
        "levels": [{
          "levelName": "New level"
        }]
      }
    ]
  }]
};

function addleveldepth(arr, depth = 1) {
  arr.forEach(obj => {
    obj.depth = depth;
    if (obj.levels) {
      addleveldepth(obj.levels, depth + 1);
    }
  });
}

addleveldepth(data.levels);

console.log(data);

Upvotes: 0

Related Questions