Recursion doesn’t seem to work very often. In fact, in some specific business scenarios, it is quite common.

Scene 1:For a multi-tier nested data structure, how do I now recursively look until I find an object whose ID is a specific reference?

This is commonly used in the tree menu, of course, we will be based on third-party component library development, third-party component library provides the corresponding event to get the current check item, if we need to handwritten. That’s where recursion comes in:

Implement a:function digui(data, id) {
 
        let value = null;
 
        for (const item of data) {
 
          if (item.id === id) {
 
            value = item;
 
            break;
 
          }
 
          if (item.children) {
 
            const _value = digui(item.children, id);
 
            if (_value) {
 
              return_value; }}}return value;
 
    } 
 
  console.log(digui(arr,999)); Method 2:let result = null

function handleDFS (arr, tid) {
 
  let i = 0;
 
  while (arr[i]) {
 
    if (arr[i].id === tid) {
 
        result = arr[i]
 
        return
 
    }
 
    if (arr[i].children) handleDFS(arr[i].children, tid)
 
    i++
 
  }
 
  return result
 
}

Copy the code

Scenario 2: Dynamically filter and obtain the last tree menu data based on the user permission code

This scenario is very common. Use recursion to get twice the result with half the effort:

Here’s example 1.

Let arr=["a","b","c","d","e"] // Let arr=["a","b"," C ","d","e"] But children have code, {name:" project 1 (1) ", children:[{name:" project 1 (1) ",code:"a"}, {name:" project 1 (2) ",code:"b"}, {name: "project a (3)," code: "KKK"},]}, {name: "project", the children: [{name: "project a (1)", code: "yyy"}, {name: "project a (2)," code: "d"}, {name: "project a (3)," code: ""},]}, {/ / class data code, keep the name:" three "project, code:" c "}, {name: "four" project, code: "d"}, / / class data without the code, {name:" item 5 ",},]Copy the code

The final result to be obtained is shown in the figure: how to achieve tiling of all items that meet the requirements?

let res=[
 {name'Item 1 (1)'.code'a'}
 {name'Item 1 (2)'.code'b'}
 {name'Item 1 (2)'.code'd'}
 {name'Item 3'.code'c'}
 {name'Item 4'.code'd'}]Copy the code

Solution:


let processUnit=(item) = >{
    const {code}=item;
    let result=null;
    if(arr.includes(code)){
        result=item
    }
    return result
}
 
let getMenu=(menu) = >{
 
    let res=[];
    menu.forEach(item= >{
       const {children}=item;
       if(Array.isArray(children)){
 
            let data=getMenu(children);
            res=[...res,...data]
       }else{
           let result=processUnit(item);
           result&&(res.push(result))
       }
    })
    return res
}
console.log("The result :",getMenu(menu))
Copy the code

For the example above, there might be another requirement in a real scenario: filter out the data that contains code in the Menu array and code in the permission list. Such as

{name: "project", the children: [{name: "project a (1)", code: "a"}, {name: "project a (2)," code: "b"}, {name: "project a (3)," code: "KKK"},]}. The item itself does not have a code, but the codes of its sub-items "Project 1" and "Project 2" are in the permission list, so the item should be retained, and the third item of the code wei "KKK" should be removed. After filtering, the item itself should look like this: {name:" item ", children:[{name:" item (1) ",code:"a"}, {name:" item (2) ",code:"b"},]}, children:[{name:" item (1) ",code:"b"},]}, children:[{name:" item (1) ",code:"b"},]}, {// Level 1 data has no code, but children have code, Children :[{name:" project 1 (1) ",code:"a"}, {name:" project 1 (2) ",code:"b"},]}, {name:" project 2 ",code:"b"},]}, {name:" project 2 ", Children: [{name: "project a (2)," code: "d"},]}, {name: "three" project, code: "c"}, {name: "four" project, code: "d"},}Copy the code

Solution:


let getMenu=(menu) = >{
 
    let res=[];
    menu.forEach(item= >{
       const {children}=item;
       if(Array.isArray(children)){
 
        lettemp={... item,children:item.children.filter(k= >arr.includes(k.code))} 
        res=[...res,temp]
       }else{
           let result=processUnit(item);
           result&&(res.push(result))
       }
    })
    return res
}
 
let processUnit=(item) = >{
    const {code}=item;
    let result=null;
    if(arr.includes(code)){
        result=item
    }
    return result
}

let res=getMenu(menu)
console.log(res)
Copy the code

Scenario 3: Data flattening: If there are subitems, they are pulled out and tiled. Finally returns a tiled array

let arr=[
    {
        catalogCode: "0"
        catalogName: "Home page"
        refImgNum: 131
    },
    {
        catalogCode: "001"
        catalogName: "Bedroom".childCatalogs:
            [
                catalogCode: "015"
                catalogName: "Master bedroom"
                refImgNum: 0] {},catalogCode: "014"
        catalogName: "The restaurant"
        refImgNum: 1}]// The final result is
arr=[
 
 {
        catalogCode: "0"
        catalogName: "Home page"
        refImgNum: 131
    },
    {
        catalogCode: "001"
        catalogName: "Bedroom"}, {catalogCode: "015"
         catalogName: "Master bedroom"
         refImgNum: 0
    },
    {
        catalogCode: "014"
        catalogName: "The restaurant"
        refImgNum: 1}]const flatArr=(ary) = >{
	let result = [];
	
	for(let i = 0; i < ary.length; i++){
		let item = ary[i];
		result.push(item);
		if (item.childCatalogs){
			result.push(...flatArr(item.childCatalogs));		
		} 
	}
	return result
}
 
export {flatArr}
Copy the code