Warning: file_get_contents(/data/phpspider/zhask/data//catemap/9/javascript/391.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
Javascript 通过嵌套元素进行映射时递归函数未按预期工作_Javascript_Reactjs - Fatal编程技术网

Javascript 通过嵌套元素进行映射时递归函数未按预期工作

Javascript 通过嵌套元素进行映射时递归函数未按预期工作,javascript,reactjs,Javascript,Reactjs,我试图递归地映射一个对象数组,它可以嵌套相同类型的对象 i、 e 有一点前提,我正在尝试构建一个导航栏菜单,其中类型为TOption的每个元素都可以有一个子菜单options字段类型为TOption。基于级别,我将在div/off-screen中抵消嵌套菜单 无论如何,当我遍历数组时,我遇到了一点麻烦。这是我的JS-ifiedrecurse方法(下面的沙箱中可以看到实际的React.useCallback函数) 上述产出 My id is 1 and I'm at level 1 My id

我试图递归地映射一个对象数组,它可以嵌套相同类型的对象

i、 e

有一点前提,我正在尝试构建一个导航栏菜单,其中类型为
TOption
的每个元素都可以有一个子菜单
options
字段类型为
TOption
。基于
级别
,我将在div/off-screen中抵消嵌套菜单

无论如何,当我遍历数组时,我遇到了一点麻烦。这是我的JS-ified
recurse
方法(下面的沙箱中可以看到实际的
React.useCallback
函数)

上述产出

My id is 1 and I'm at level 1 
My id is 4 and I'm at level 3 
My id is 5 and I'm at level 1 
很明显,它只进入有子菜单的元素,递归以没有子菜单的菜单结束

我怎样才能改变它,使输出变成

My id is 1 and I'm at level 1
My id is 2 and I'm at level 1
My id is 3 and I'm at level 2
My id is 4 and I'm at level 3
My id is 5 and I'm at level 1
// Where those at level 1 would be displayed in the "parent" menu,
// and those at level 2 would be a secondary submenu of that parent menu,
// and those at level 3 would a submenu of a secondary menu.
第3级菜单的一个例子是
设置->布局->主题
,其结构是

const options = [
  ...restOfOptions
  {
    id: "2",
    name: "Settings",         // level 1
    options: [
      {
        id: "3",
        name: "Layout",       // level 2
        options: [
          {
            id: "4",
            name: "Theme",    // level 3
          }
        ]
      }
    ]
  },
];
这里的问题是,如果存在子菜单,那么函数将返回该树中存在的最后一个子菜单

在沙箱中,输出为

My id is 1 and I'm at level 1
        My id is 4 and I'm at level 3
            My id is 6 and I'm at level 4
My id is 7 and I'm at level 1
但我在寻找

My id is 1 and I'm at level 1
My id is 2 and I'm at level 1
    My id is 3 and I'm at level 2
        My id is 4 and I'm at level 3
        My id is 5 and I'm at level 3
            My id is 6 and I'm at level 4
My id is 7 and I'm at level 7
在“subOptions.length”控件中,如果存在子选项,则不会写入当前数据,因为您使用递归

事实上,您需要先写入当前数据,然后在它有子选项时调用它。

在“subOptions.length”控件中,如果有子选项,您将不会写入当前数据,因为您使用递归


事实上,您需要先写入当前数据,然后在有子选项时调用它。

如下更改代码:

       const recurse = React.useCallback(
         ({ options, level }) =>
           options.map(({ id, name, options: subOptions = [] }) =>{
              console.log(level)
    
              let elem=[];
              let smallelem=subOptions.length>0 ? (
               recurse({ options: subOptions, level: level + 1 })
               ):null;
              elem.push(<div key={id} style={{ paddingLeft: level === 1 ? 0 : level * 40 }}>
                   My id is {id} and I'm at level {level}
                </div>)
              elem.push(smallelem)
              return elem;
         }
        ),
      []
      );
const recurse=React.useCallback(
({选项,级别})=>
options.map({id,name,options:subOptions=[]})=>{
console.log(级别)
设elem=[];
设smallelem=子选项。长度>0(
递归({选项:子选项,级别:级别+1})
):null;
元素推(
我的id是{id},我在{level}
)
元素推动(smallelem)
返回元素;
}
),
[]
);

如下更改代码:

       const recurse = React.useCallback(
         ({ options, level }) =>
           options.map(({ id, name, options: subOptions = [] }) =>{
              console.log(level)
    
              let elem=[];
              let smallelem=subOptions.length>0 ? (
               recurse({ options: subOptions, level: level + 1 })
               ):null;
              elem.push(<div key={id} style={{ paddingLeft: level === 1 ? 0 : level * 40 }}>
                   My id is {id} and I'm at level {level}
                </div>)
              elem.push(smallelem)
              return elem;
         }
        ),
      []
      );
const recurse=React.useCallback(
({选项,级别})=>
options.map({id,name,options:subOptions=[]})=>{
console.log(级别)
设elem=[];
设smallelem=子选项。长度>0(
递归({选项:子选项,级别:级别+1})
):null;
元素推(
我的id是{id},我在{level}
)
元素推动(smallelem)
返回元素;
}
),
[]
);

递归可用于在任何深度解压元素。 这就是如何将此递归解决方案插入函数的方法:

function rec(arr) {

  arr.forEach((elem) => {
    if (elem.options === undefined) { // belongs to level 1
        console.log("Element id", elem.id)
    }
    else {
        for (let a in elem.options) {
            console.log("Element id", elem.id)
            return `Element id: ${elem.id} ${rec([elem.options[a]])}`;
        }
    }   
        
  });
}
测试:


递归可以用于在任何深度解压元素。 这就是如何将此递归解决方案插入函数的方法:

function rec(arr) {

  arr.forEach((elem) => {
    if (elem.options === undefined) { // belongs to level 1
        console.log("Element id", elem.id)
    }
    else {
        for (let a in elem.options) {
            console.log("Element id", elem.id)
            return `Element id: ${elem.id} ${rec([elem.options[a]])}`;
        }
    }   
        
  });
}
测试:


我想没有一个答案对你有任何帮助?我想没有一个答案对你有任何帮助?
rec(options);

/**
* Element id 1
* Element id 2
* Element id 3
* Element id 4
* Element id 5
*/