js handles recursive problems elegantly with iterator pattern

Keywords: Front-end Attribute JSON

What is an iterator

Each value in a circular array or object has already provided an iterator natively in js.

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

Implementing an iterator

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)

/*
Print:
item is 1
index is 0
item is 2
index is 1
item is 3
index is 2
*/

practical application

Demand:

  • Antd's nested table components have data source requirements. If there are no child elements, the child attribute should be set to null or delete the child attribute. In the actual development, when the back-end interface returns no child elements, the child attribute should be set to an empty array.
  • The field name categoryId returned from the back end is changed to value, and the name field name is changed to label.

Examples before and after data structure modification.

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

// After processing, the data structure is as follows

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

The iterator pattern is used to handle recursive classification elegantly.

// data source
var categoryList = [
    {
        categoryId: 1,
        name: '1 level',
        children: [
            {
                categoryId: 11,
                name: '11 level',
                children: [],
            },
        ],
    },
    {
        categoryId: 2,
        name: '2 level',
        children: []
    }
]

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

// Processing each item
var changeItem = function (item) {
    // Change field name
    item.value = item.categoryId
    item.label = item.name
    delete item.categoryId
    delete item.name

    // When children is an empty array, delete the children attribute
    if (item.children == false) {
        delete item.children
    } else {
        iterator(item.children, changeItem)
    }
}

// Call an iterator
iterator(categoryList, changeItem)
console.log(JSON.stringify(categoryList, null, 4))

/*
Print:
[
    {
        "children": [
            {
                "value": 11,
                "label": "11 Grade "
            }
        ],
        "value": 1,
        "label": "1 Grade "
    },
    {
        "value": 2,
        "label": "2 Grade "
    }
]
*/

summary

Recursive function reference iterator patterns are needed to write more elegant and readable code.

Posted by ADLE on Tue, 02 Apr 2019 20:03:28 -0700