有這樣一個數組,它的每個數組項都包含children屬性,children也是一個結構一模一樣的數組
let arr = [
{
name: 'zzh',
key: '1',
children: [
{
name: 'aaa',
key: '1-1',
children: []
},
{
name: 'bbb',
key: '1-2',
children: []
},
{
name: 'ccc',
key: '1-3',
children: []
}
]
},
{
name: 'yh',
key: '2',
children: [
{
name: 'qqq',
key: '2-1',
children: [
{
name:'fff',
key:'2-1-1',
children:[]
}
]
},
{
name: 'www',
key: '2-2',
children: []
},
{
name: 'eee',
key: '2-3',
children: []
}
]
}
]
我要在此數組中通過name尋找一個值,並將它的key保存,如何實現?
首先這個數組的層級不確定,children可能一直有children,所以這裏我要用遞歸來做
- 遍歷數組,首先判斷當前項是否是要尋找的值
- 若當前項不是要尋找的值,則判斷是否有children,有children則遞歸調用
function test (arr, name) {
for (let item of arr) {
//首先判斷是否有值存在,有則return打斷循環
if (item.name === name) {
return item.key
}
//當上面判斷不成立時,判斷它有沒有children,有則調用test去children中尋找
if(item.children && item.children.length){
let i = test(item.children,name) //這裏很重要,保存children尋找的結果,如果children找到則返回出去
if(i){
return i
}
}
}
return null
}
console.log(test(arr, 'fff'))
爲了減少循環,只要有符合條件的值就會打斷遍歷,所以上面的只會尋找第一個出現的值,如果要找到每個值則用for或forEach
2.現在要尋找一個值,並且返回這個值的層級結構,比如要尋找name爲fff,它的層級結構爲:“2”,“2-1”,“2-1-1”。
當然我們這裏的key很有規律,知道值的key就能推斷它的父級。假設不能通過此規律尋找,如何來尋找層級結構?
剛開始的時候一直不知道怎麼做,想到的方法是遍歷每個元素,然後通過上面的函數判斷後代是否存在,但是這樣不就又多遍歷了一次嗎,其實上面的函數已經遍歷了數組,我們可以直接根據上面的函數判斷,並保存值即可
let result = []
function test (arr, name,result) {
for (let item of arr) {
//首先判斷是否有值存在,有則return打斷循環
if (item.name === name) {
return item.key
}
//當上面判斷不成立時,判斷它有沒有children,有則調用test去children中尋找
if(item.children && item.children.length){
let i = test(item.children,name,result) //這裏很重要,保存children尋找的結果,如果children找到則返回出去
if(i){
result.push(item.key)
return i
}
}
}
return null
}
test(arr,'fff',result)
console.log(333,result)
上面的弊端就是順序是相反的,因爲只有遍歷到最後才知道後代是否存在
這是我在工作中遇到的一個問題:
當我搜索一個值時,自動展開,這樣對搜索的值一目瞭然,上面是用antd的Table組件做的,要展開每一級就需要設置展開的keys,所以我需要層級結構,我使用的是id作爲key,所以也不存在上面的那種直接獲得層級的規律。搜索值在一級層級之間可以重複,1一級以下不重複,所以一級用forEach,後代再用的函數遍歷