如何优化多层嵌套的循环和条件判断代码?

逻辑稍微复杂点,就很容易出现for循环中嵌套if语句。比如:

menus:[{
        id:"index",
        title:"首页",
        isVisible:true
    },{
        id:"apps",
        title:"应用中心",
        isVisible:true,
        children:[{
                id:"index",
                title:"首页",
                isVisible:true
            }
        ]
    }
]

这段代码先遍历menus数组,然后判断是否显示,在判断是否有二级栏目,再遍历二级栏目。。简化版代码:

for(var i=0;i<menus.length;i++){
    if(menus[i].isVisible == true){
        dosomething....
        if(menus[i].children){
            for(var j=0;j<menus[i].children.length;j++){
                if(menus[i].children[j].isVisible == true){
                    dosomething.....
                }
            }
        }
    }
}

有些代码检测工具是不赞同多层for/if 等嵌套的,最多三层,但这段代码都有五层嵌套了。。 求教各位大神,这类代码应该怎么优化? 感谢感谢!!

阅读 15.6k
6 个回答

请使用递归。

var menus=[{
        id: "index",
        title: "首页",
        isVisible: true
    },
    {
        id: "apps",
        title: "应用中心",
        isVisible: true,
        children: [{
                id: "11",
                title: "aaa",
                isVisible: true,
                children:[{
                    id: "12",
                    title: "bbb",
                    isVisible: true,
                    children:[{
                        id: "13",
                        title: "ccc",
                        isVisible: true
                    }]
                }]
            }
        ]
    }
];


function func(array) {

    for(var i=0;i<array.length;i++)
    {
        if(array[i].isVisible){
            console.log(array[i].id)
        }
        if(array[i].children)
        {
            func(array[i].children);
        }
    }

}
console.time('time');
func(menus);
console.timeEnd('time');

这种含有子元素children,并且子元素和父级元素的结构是相似的,明显应该用递归或者while来进行遍历嘛。

(function forEach(menus){
    for(var i = 0; i < menus.length; i++){
        //这里的 == true 完全没有必要
        if(menus[i].isVisible){
            //dosomething....
            if(menus[i].children){
                //有子元素,那么就递归
                forEach(menus[i].children);
            }
        }
    }
})(menus);

换种写法可以降到3层:

// 第一层
for(var i=0;i<menus.length;i++){
  // 为了减少层次,先判断不符合的情况                                                 
  if(menus[i].isVisible != true){                                                
    continue;                                                                    
  }                                                                              
  dosomething....;  // isVisible == true
  // 第二层                                      
  if(menus[i].children){
    // 第三层                                                         
    for(var j=0;j<menus[i].children.length;j++){
      // 为了减少层次,先判断不符合的情况                                      
      if(menus[i].children[j].isVisible != true){                                   
        continue;                                                                   
      }                                                                             
      dosomething.....                                                              
    }                                                                               
  }                                                                                 
}

看看是不是可以这样?
for(var i=0;i<menus.length;i++){

if(menus[i].isVisible != true){
    continue;
}
dosomething....
if(!menus[i].children){
     continue;
}  
for(var j=0;j<menus[i].children.length;j++){
    if(menus[i].children[j].isVisible != true){
          continue;     
    } 
    dosomething.....       
}      

}

function fn(arr) {
  if (!Array.isArray(arr)) return;
  arr.forEach((item) => {
    if (!item.isVisible) return;
    // dosomething....
    console.log(item.title);
    if (item.children && Array.isArray(item.children) && item.children.length > 0) fn(item.children);
  });
}
fn(menus)
新手上路,请多包涵

我用的是map遍历 也用到了递归

//根据后台数据格式化菜单
function formatMenu(data) {
    return data.map(function (item) {
        if (!item||!item.isVisible) {
            return null;
        }
        var result = {...item}
        if (item.children) {
            var children = formatMenu(item.children);
            result.children = !!children ? children : null;
        }
        return result;
    }).filter(function (item) {
        return item
    });
}
撰写回答
你尚未登录,登录后可以
  • 和开发者交流问题的细节
  • 关注并接收问题和回答的更新提醒
  • 参与内容的编辑和改进,让解决方法与时俱进
推荐问题