Using reduce () method to process tree data

Time:2021-5-7

definition

reduce()Method performs a task provided by you for each element in the arrayreducerFunction (executed in ascending order) to aggregate its results into a single return value.

Like foreach(), map(), and filter(), reduce() will traverse every item in the array, but reduce() can calculate the result of the previous array item and the current one.

grammar

array.reduce(function(prev, cur, index, array){  
 ...  
}, init)

Parameters in callback function:

  • prevRequired. Represents the return value or initial value init when calling the callback.
  • curRequired. Represents the current element.
  • indexOptional. Represents the index of the current element.
  • arrayRepresents the original array.
  • initOptional. Initial value, as the first parameter of the callback function for the first time.

The common parameters are as follows:prevandcur

be careful: when the callback function is executed for the first time, prev and cur have two values: if the initial value init is provided when reduce() is called, prev takes the init value, cur takes the first value in the array, and the index starts from 0; If init is not provided, prev takes the first value in the array, cur takes the second value in the array, and the index starts from 1.

example

1. The initial value init is not passed

const arr = [1, 3, 5, 7]  
    arr.reduce(function(prev, cur, index, arr){  
    console.log(prev, cur, index)  
    return prev + cur  
})

The parameters and return values of each call are as follows:

callback prev cur index array return value
The first time 1 3 1 [1, 3, 5, 7] 4
The second time 4 5 2 [1, 3, 5, 7] 9
The third time 9 7 3 [1, 3, 5, 7] 16

Because no initial value is passed in, the index starts from 1, and the callback is called three times. At the beginning, the value of prev is the first item 1 of the array, and the value of cur is 3. After adding, the value of 4 is returned as the prev value of the next round of callback, and then the next round of callback is continued until it is completed.

2. When the initial value is transferred

const arr = [1, 3, 5, 7]  
arr.reduce(function(prev, cur, index, arr){  
    console.log(prev, cur, index)  
    return prev + cur  
}, 10)

The parameters and return values of each call are as follows:

callback prev cur index array return value
The first time 10 1 0 [1, 3, 5, 7] 11
The second time 11 3 1 [1, 3, 5, 7] 14
The third time 14 5 2 [1, 3, 5, 7] 19
The fourth time 19 7 3 [1, 3, 5, 7] 26

3. Array de duplication

const arr = ['ab', 'v', 'd', 'ab', 'h', 'e', 'dc', 'e', 'e', 'f']  
    const newArr = arr.reduce(function(prev, cur){  
    !prev.includes(cur) && prev.push(cur)  
    return prev  
}, [])  
console.log(newArr) // ["ab", "v", "d", "h", "e", "dc", "f"]~~~~

The steps are as follows:

  • Initialize an empty array
  • When called for the first time, prev is the initial value, that is, the empty array, cur is the first item in the array, arr [1]. Then find out whether cur already exists in prev, if not, add the item to prev, and prev returns to enter the next callback
  • In the second callback, prev is the return value of the first time, cur is the second item in the array arr [2], and then find out whether cur already exists in prev, if not, add the item to prev, and prev returns to enter the next callback
  • … …
  • Finally, the prev array is returned

4. Use reduce to group and merge the objects in the array

//The object array obtained from the background is grouped according to the type of the object and merged into a tree to display the data
const dataArr = [
    {type: 'governance layer', name: 'hive'_ 82', reserve: '2', id: 1 },
    {type: 'original data layer', name: 'qwe', reserve: '1', ID: 2},
    {type: 'paste source layer', name: 'MySQL'_ exchangis', reserve: '3', id: 3 },
    {type: 'governance layer', name: 'links_ 188', reserve: '1', id: 4 },
    {type: 'paste source layer', name: 'MySQL'_ ces', reserve: '2', id: 5 }
]

const treeData = dataArr.reduce((cur, next) => {
    const obj = cur.find(curItem => curItem.label === next.type) 
    if (obj) { 
        If (obj. Children. Indexof (next. ID) = = = - 1) {// de reprocessing
            obj.children.push({ 
                ...next, 
                label: next.name 
            })
        }
    } else {
        const newObj = {
            label: next.type,
            children: [{
                ...next,
                label: next.name
            }]
        }
        cur.push(newObj)
    } return cur
}, [])

​console.log(treeData)

The results are as follows:

[
    {
        Label: 'governance level',
        children: [
            {type: 'governance layer', name: 'hive'_ 82', reserve: '2', id: 1, label: 'hive_ 82' },
            {type: 'governance layer', name: 'links_ 188', reserve: '1', id: 4, label: 'links_ 188' }
        ]
    },
    {
        Label: 'original data layer',
        children: [
            {type: 'original data layer', name: 'qwe', reserve: '1', ID: 2, label: 'qwe'}
        ]
    },
    {
        Label: 'paste source layer',
        children: [
            {type: 'paste source layer', name: 'MySQL'_ exchangis', reserve: '3', id: 3, label: 'mysql_ exchangis' },
            {type: 'governance layer', name: 'MySQL'_ ces', reserve: '2', id: 5, label: 'mysql_ ces' }
        ]
    }
]

5. Use reduce to process the menu. The structure of the menu returned by the back end is as follows

Method 1

const dataArr = [
    {ID: '18', name: 'reset password', parentid: '30', parentname: 'user management'}, 
    {ID: '13', name: 'audit log', parentid: '29', parentname: 'system management'}, 
    {ID: '29', name: 'system management', parentid: '0', parentname: null}, 
    {ID: '14', name: 'modify', parentid: '33', parentname: 'department management'}, 
    {ID: '2', name: 'user list', parentid: '30', parentname: 'user management'}, 
    {ID: '30', name: 'user management', parentid: '29', parentname: 'system management'}, 
    {ID: '33', name: 'department management', parentid: '0', parentname: null}, 
    {ID: '37', name: 'Add User', parentid: '30', parentname: 'user management'}, 
    {ID: '6', name: 'Add', parentid: '33', parentname: 'department management'}, 
    {ID: '7', name: 'Delete', parentid: '33', parentname: 'department management'}
] 

//Create the mapping relationship of menu ID
const idMapping = dataArr.reduce((prev, next, i) => {
    prev[next.id] = i return prev
}, {})
​
const treeData = []
Dataarr. Map (EL = > {// first level menu)
    if (el.parentId === '0') {
        Treedata. Push (EL) return} // find parent element by mapping
    const parentEl = dataArr[idMapping[el.parentId]] 
// add the current element to the 'children' array of the parent element
    parentEl.children = [...(parentEl.children || []), el]
})
console.log(treeData)

Method 2

//Create mapping relationship based on parentid
const result = dataArr.reduce((prev, next) => {
    prev[next.parentId] ? prev[next.parentId].push(next) : prev[next.parentId] = [next]; 
    return prev;
}, {});
      
Object.keys(result).map(key => {
    result[key].map((item, i) => {
        result[item.id] ? item.children = result[item.id] : '' });
}) 
this.treeData = result[0]
console.log(treeData)

It can also be realized by recursion, which is not detailed

Finally, the generated data structure is shown as follows:
Using reduce () method to process tree data