js 用迭代器模式优雅的处理递归问题

更新日期: 2019-04-02阅读: 2k标签: 递归

什么是迭代器

循环数组或对象内每一项值,在 js 里原生已经提供了一个迭代器。

var arr = [1, 2, 3]
arr.forEach(function (item) {
	console.log(item)
})


实现一个迭代器

var iterator = function (arr, cb) {
	for (let i = 0; i < arr.length; i++) {
  	cb.call(arr[i], arr[i], i)
  }
}

var cb = function (item, index) {
  console.log('item is %o', item)
  console.log('index is %o', index)
}

var arr = [1, 2, 3]
iterator(arr, cb)

/*
打印:
item is 1
index is 0
item is 2
index is 1
item is 3
index is 2
*/


实际应用

需求:

  • Antd 的嵌套表格组件的数据源有要求,如果没有子元素,children 属性应该设置为 null 或者删除 children 属性,实际开发中后端返回的接口却是没有子元素时,children 属性设置为一个空数组;
  • 后端返回的字段名 categoryId 字段名更改为 value,name 字段名更改为 label。

数据结构修改前后示例。

var categoryList = [
    {
        categoryId: 1,
        name: '1级',
        children: [
            {
                categoryId: 11,
                name: '11级',
                children: [],
            },
        ],
    },
    {
        categoryId: 2,
        name: '2级',
        children: []
    }
]

// 处理之后数据结构如下

var categoryList = [
    {
        value: 1,
        label: '1级',
        children: [
            {
                value: 11,
                label: '11级',
            },
        ],
    },
    {
        value: 2,
        label: '2级',
    }
]

使用迭代器模式优雅的处理递归类问题。

// 数据源
var categoryList = [
    {
        categoryId: 1,
        name: '1级',
        children: [
            {
                categoryId: 11,
                name: '11级',
                children: [],
            },
        ],
    },
    {
        categoryId: 2,
        name: '2级',
        children: []
    }
]

// 迭代器
var iterator = function (arr, cb) {
    for (let i = 0; i < arr.length; i++) {
        cb.call(arr[i], arr[i])
    }
}

// 处理每一项
var changeItem = function (item) {
    // 更改字段名称
    item.value = item.categoryId
    item.label = item.name
    delete item.categoryId
    delete item.name

    // 当 children 为空数组时,删除 children 属性
    if (item.children == false) {
        delete item.children
    } else {
        iterator(item.children, changeItem)
    }
}

// 调用迭代器
iterator(categoryList, changeItem)
console.log(JSON.stringify(categoryList, null, 4))

/*
打印:
[
    {
        "children": [
            {
                "value": 11,
                "label": "11级"
            }
        ],
        "value": 1,
        "label": "1级"
    },
    {
        "value": 2,
        "label": "2级"
    }
]
*/


总结

凡是需要用到递归的函数参考迭代器模式,能写出更优雅,可读性更高的代码


链接: https://www.fly63.com/article/detial/2694

js递归函数——函数体内调用本函数的方式

在js中通过如果一个函数直接或间接调用函数本身,则该函数称为递归函数。

原生js实现树级递归,通过js生成tree树形菜单(递归算法)

JavaScript生成树形菜单需求:首先这是一个数据集—js的类型,我们需要把生成一个tree形式的对象 : id,与pid之间的对应关系,当pid不存在,或pid:0的时候,这一项,应该为树的顶端,那么我们需要去重新建一次索引。

Vue一个案例引发的递归组件的使用

什么是递归组件?简单来说就是在组件中内使用组件本身,下面我们就来看看如何在项目中使用递归组件去解决我们上面问题。类似与信息分类的展示在我们的项目中是非常常见的形式,我们利用递归组件可以很好的去解决问题

JavaScript实现无限级递归树

最近遇到一个需求,平时被后台惯着直接返回了树形结构给到前端,前端对这种嵌套类型的数据(如地区的级联或菜单的树形结构)省掉了一层处理。换了个后台开发返回了扁平化的数组数据给到前端自己去处理如下data。突然有点慌......

Js中的递归

递归函数是在一个函数通过名字调用自身的情况下构成的,这种写法在函数有名字,而且名字以后也不会变的情况下是没有问题的。但是函数的执行与函数名factorial紧紧耦合在了一起

递归与循环的区别

递归:你打开面前这扇门,看到屋里面还有一扇门(这门可能跟前面打开的门一样大小(静),也可能门小了些(动)),你走过去,发现手中的钥匙还可以打开它,你推开门,发现里面还有一扇门,你继续打开

递归获取页面元素的真实offsetLeft和offsetTop

由于父元素的定位属性, 导致子元素及其孙元素等的offsetLeft和offsetTop变得和预期不一致(预期上都是到屏幕左边和上边的位置), 由于需要做鼠标拖动旋转和鼠标框选

JS递归及二叉搜索树的移除节点

递归含义:在某时某刻某个条件下调用包含自己的函数;注意点:⑴递归过程中一定要加限制条件,要不然会陷入死循环:递归有个过程,不是一步到位的,这一点尤其重要

js利用递归与promise 按顺序请求数据

项目中有一个需求,一个tabBar下面如果没有内容就不让该tabBar显示,当然至于有没有内容,需要我们通过请求的来判断,但是由于请求是异步的,如何让请求按照tabBar的顺序进行?

递归算法的理解和用法

所谓递归,就是既有传递,又有回归,与其说是传递与回归,初学不如理解是一种 “循序递进”与“规律约束”。为什么这样说,因为递归算法相比较于循环在代码结构方面个人认为更加简洁清晰,清晰易懂,递归注重的是一种有序的规律

点击更多...

内容以共享、参考、研究为目的,不存在任何商业目的。其版权属原作者所有,如有侵权或违规,请与小编联系!情况属实本人将予以删除!