递归遍历多层嵌套对象组合数据

821 阅读1分钟

递归可以一定程度的简化代码,要学会善于运用递归

    let obj = {
    'a':[{'v':[5,{'ewq':[8]}]}],
    'b':{'to':[{'yy':[5,6]}],'yuy':88},
    'ee':[4,6],
    'c':9,
    'e':[4,6],
    'to':{'ttt':'po'}
}

输出结果:
['a.list.v.list.5', 'a.list.v.list.ewq.list.8', 'b.to.list.yy.list.5', 'b.to.list.yy.list.6', 'b.yuy.88', 'ee.list.4', 'ee.list.6', 'c.9','e.list.4', 'e.list.6', 'to.ttt.po']

首先分析数据结构,可以看出obj是一个多层嵌套的对象,输出结果是一个数组。很快就想到了遍历对象,然后把结果放进去数组里面。遍历数组,最开始想到使用for...in,可是这个拿value值的时候,要使用一层.语法,看着没有那么好看。

    for(let i in obj){
        console.log('key=====',i)
        console.log('value=====',obj[i])
    }

后面用了 Object.entries 和 for...of结合

for (let [key,value] of Object.entries(obj)) {
       console.log(key)
       console.log(value)
   }

开始正题,可以看到分为3种输入类型,一种是对象,一种是数组,一种是基本类型值;得到的输出结果分别是key.value/key.list.value/.value 。对于数组和对象还要继续遍历,直到是基本类型值,结束遍历。

    let res = []
    //假设输入的变量为www
   if(Array.isArray(www)){
       for(let r = 0;r<www.length;r++){
            // 这里要拼接上 '.list'
       }
   }else if(Object.prototype.toString.call(www) == '[object Object]'){
      for (let [key,value] of Object.entries(www)) {
          // 这里要拼接上 `.${key}`
      }
   }else{
      //这里要拼接上 `.${www}`
   }

因为遍历的每一项又可能是数组,或者对象吗、,或者基本类型值,我们会发现这就重复了。

所以声明一个函数,当重复的地方用函数替代即可

let res = []

function origin(obj) {
   for (let [key,value] of Object.entries(obj)) {
      swap(value,key)
   }
   return res
}

function swap(www,res1 = '') {
   if(Array.isArray(www)){
       for(let r = 0;r<www.length;r++){
          swap(www[r],res1  + '.list')
       }
   }else if(Object.prototype.toString.call(www) == '[object Object]'){
      for (let [key,value] of Object.entries(www)) {
         swap(value,res1 + '.'+key )
      }
   }else{
      res.push(res1 + '.' + www)
   }
} 

可以看到现在的一个输出结果就是 ['a.list.v.list.5', 'a.list.v.list.ewq.list.8', 'b.to.list.yy.list.5', 'b.to.list.yy.list.6', 'b.yuy.88', 'ee.list.4', 'ee.list.6', 'c.9', 'e.list.4', 'e.list.6', 'to.ttt.po']