【问题标题】:How to add item to each level of a nested array如何将项目添加到嵌套数组的每一级
【发布时间】:2022-01-14 10:55:35
【问题描述】:

我在每个对象中都有无限级别数组,我想根据级别添加“id”。假设如果级别 1 则 id 应为 1,而级别 2 则 id 将为 2,依此类推。

{
"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"
                    }
                ]
            }
        ]
    }
]

}

我想将上面的数组转换成下面的新数组。我尝试使用 for 循环,但它不起作用我没有得到预期的数据。我想根据级别添加“id”。假设如果级别 1 则 id 应为 1,而级别 2 则 id 将为 2,依此类推。

{
"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"
                    }
                ]
            }
        ]
    }
]

}

【问题讨论】:

  • 建议:术语“id”表示这些是唯一值。在这种情况下,将其称为“级别”可能更有意义。
  • 感谢您的建议,我已经编辑了我的问题

标签: javascript arrays reactjs object


【解决方案1】:

您可以采用递归方法并为每个级别移交一个递增的级别。

addLevels 接受一个级别变量并返回另一个函数,它将levels 与对象分开。对象的其余部分是一个新变量。

内部函数返回一个带有level 属性的新对象、一个不带levels 的旧对象和一个用于获取嵌套数组映射的属性levels

addLevellevel 上具有 closure,它保留了嵌套函数的值。

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; }

【讨论】:

  • 你能告诉我这个解决方案是如何工作的吗?这有点神奇!
  • @AlexandrBelan,请参阅编辑。
  • @AlexandrBelan 你可以认为这段扭曲的代码看起来很神奇,但根据jsbench.me 的说法,它比我的旧while 循环stackoverflow.com/a/70725822/6316468 慢100%。
【解决方案2】:

这里我称这个属性为“深度”:

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);

【讨论】:

    【解决方案3】:

    认为它有效:

    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}

    【讨论】:

    • 感谢您的帮助,但使用上述 user6316468 解决方案。
    【解决方案4】:

    这是一个使用堆栈和 while 循环的简单解决方案。

    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);

    【讨论】:

    • 这很好用,非常感谢。
    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 2020-07-01
    • 1970-01-01
    • 1970-01-01
    • 2019-02-11
    • 2022-07-02
    • 1970-01-01
    • 2020-05-29
    相关资源
    最近更新 更多