关于递归在项目中的几种常用应用

项目中常常会对开发返回的json数据进行遍历,然后更新页面,如果数据只是简单的一层结构,只需一个for循环即可搞定,但如果数据存在较深且不确定的层次,此时就需要使用递归配合循环来搞定,先看下模拟的数据格式:

//json数据
var json = {
    status: 'success',
    data: [
        {
            status: 0,
            title: '文件夹1',
            data: [
                {
                    status: 0,
                    title: '文件夹2',
                    data: [
                        {
                            status: 0,
                            title: '文件夹3',
                            data: [
                                {
                                    status: 0,
                                    title: '文件夹4',
                                    data: []
                                },
                                {
                                    status: 0,
                                    title: '文件夹4',
                                    data: []
                                }
                            ]
                        },
                        {
                            status: 0,
                            title: '文件夹3',
                            data: []
                        }
                    ]
                },
                {
                    status: 0,
                    title: '文件夹2',
                    data: []
                }
            ]
        },
        {
            status: 1,
            title: '文件1',
        }
    ]
};

对于上面这种深层次的数据结构,普通的循环是无法搞定的,此时可以提取重复处理的代码片段,然后使用递归 即可搞定,直接看代码:

/**
 * 递归遍历数据
 */
function recursion(data) {
    var i = 0,
        len = data.length,
        j, item, current, flag;

    for (; i < len; i++) {
        item = data[i];

        for (j in item) {
            current = item[j];
            //是否数组判断
            flag = (Object.prototype.toString.call(current) === '[object Array]') ? true : false;

            if (flag) {
                recursion(current);
            } else {
                //这里执行对数据的相应操作
                console.log(current);
            }
        }
    }
}

//调用
recursion(json.data);

一个类似的应用是DOM节点的游走,可以遍历整个文档所有节点,包括子节点,看如下代码:

/**
 * 节点遍历
 */
function nodeWalk(node, fn) {
    var re = arguments.callee; //引用函数本身

    if (node.nodeType === 1) {
        //处理节点
        fn.call(node, node);
    }

    node = node.firstChild;

    while (node) {
        re(node, fn);
        node = node.nextSibling;
    }

}

//调用
nodeWalk(document.body, function(n){
    console.log(this.nodeName);
});

还有一种典型用例是,对于多行的input需要往后端ajax实时验证输入内容的时候,普通的for循环已不能解决问题,需要在ajax请求成功的回调函数里进行递归调用,直接看示例代码:

//初始化
var nodeList = $('#test input:text'),
    n = 0;

/**
 * 递归验证
 */
(function recursionCheck(node) {

    var v = node.value,
        nextNode = nodeList[++n];

    //ajax请求服务端验证
    $.ajax({
        'url': 'xxxxx.do',
        'data': 'xxxxxx',
        'dataType': 'json',
        'success': function(data){

            //验证成功,递归调用代码验证下一个node
            if (data.value === v) {

                //判断节点是否存在
                if (nextNode) {
                    recursionCheck(nextNode);
                } else {
                    alert('验证通过');
                }
            } 

            //验证不成功,结束执行,给出错误提示
            else {
                alert('数据验证不正确');
            }
        }
    });

})(nodeList[n]);

只有可怜的一条评论

  1. 以前也这么递归遍历数据,后来发现不用递归也可以做。复习了一下数据结构的东西。

发表评论

>>
后台管理 工具库 RSS 微博 简历