1. 程式人生 > >js 用迭代器模式優雅的處理遞迴問題

js 用迭代器模式優雅的處理遞迴問題

開發十年,就只剩下這套架構體系了! >>>   

什麼是迭代器

迴圈陣列或物件內每一項值,在 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級"
    }
]
*/

總結

凡是需要用到遞迴的函式參考迭代器模式,能寫出更優雅,可讀性