美文网首页
[记录]多级数组遍历的几种方式

[记录]多级数组遍历的几种方式

作者: 柏丘君 | 来源:发表于2018-08-31 18:00 被阅读0次

    有一个需求:从类似下面数组中,将 id 提取出来,放入另一个数组中:

    const a = [
      {
          test:[{id:1},{id:2}]
      },{
          test:[{id:3},{id:4},{id:5}]
      },{
          test:[{id:6},{id:7},{id:8}]
      },{
        test:[{id:9}]
      }
    ]
    

    对于这个问题,首先我想到的是这个方案:

    function convert(a){
      const b = [];
      a.forEach(v1 => {
        const tmp = [];
        v1.test.forEach(v2 => tmp.push(v2))
        b.push(...tmp)
      })
      return b;
    }
    

    如果将 forEach 换成普通的 while 循环,应该会具备更快的运行速度:

    function conver2(a){  
      const b = [];
      let i = 0;
      let arrLen = a.length;
      while(i < arrLen){
        let testLen = a[i].test.length;
        let j = 0;
        while(j < testLen){
          b.push(a[i].test[j])
          j++
        }
        i++
      }
      return b;
    }
    

    冥冥之中,我感觉是可以通过一层循环来解决这个问题的,于是想出了第三种方案:

    function convert3(a){
      let i = j = 0;
      let testLen = a[j].test.length;
      let arrLen = a.length;
      let b = [];
    
      while(j < arrLen){
        b.push(a[j].test[i].id);
        i++
        if(i == testLen){
          j++;
          i = 0
          if(j < arrLen){ 
            testLen = a[j].test.length
          }
        }
      }
      return b;
    }
    

    为了衡量三种算法的性能,需要使用较大的操作数量,于是我将代码做了一些修改,来统计这三个方法各自的执行时间:

    const a = [
      {
          test:[{id:1},{id:2}]
      },{
          test:[{id:3},{id:4},{id:5}]
      },{
          test:[{id:6},{id:7},{id:8}]
      },{
        test:[{id:9}]
      }
    ]
    
    for(let i = 0; i < 1000000;i ++){
      a.push(a[i % a.length])
    }
    
    function convert1(a,index){
      console.time("start-convert1-"+index);
      const b = [];
      a.forEach(v1 => {
        const tmp = [];
        v1.test.forEach(v2 => tmp.push(v2))
        b.push(...tmp)
      })
      console.timeEnd("start-convert1-"+index);
    }
    
    function convert2(a,index){
      console.time("start-convert2-"+index);
      const b = [];
      let i = 0;
      let arrLen = a.length;
      while(i < arrLen){
        let testLen = a[i].test.length;
        let j = 0;
        while(j < testLen){
          b.push(a[i].test[j])
          j++
        }
        i++
      }
      console.timeEnd("start-convert2-"+index);
    }
    
    function convert3(a,index){
      console.time("start-convert3-"+index);
      let i = j = 0;
      let testLen = a[j].test.length;
      let arrLen = a.length;
      let b = [];
    
      while(j < arrLen){
        b.push(a[j].test[i].id);
        i++
        if(i == testLen){
          j++;
          i = 0
          if(j < arrLen){ 
            testLen = a[j].test.length
          }
        }
      }
      console.timeEnd("start-convert3-"+index);
    }
    
    for(let i = 0; i < 10; i++){
      convert1(a,i)
      convert2(a,i)
      convert3(a,i)
    }
    

    运行结果如下:

    start-convert1-0: 151.4248046875ms
    start-convert2-0: 75.463134765625ms
    start-convert3-0: 59.9140625ms
    start-convert1-1: 133.663818359375ms
    start-convert2-1: 54.760986328125ms
    start-convert3-1: 58.22607421875ms
    start-convert1-2: 135.48095703125ms
    start-convert2-2: 56.72314453125ms
    start-convert3-2: 53.788818359375ms
    start-convert1-3: 147.720703125ms
    start-convert2-3: 58.44091796875ms
    start-convert3-3: 54.409912109375ms
    start-convert1-4: 143.4169921875ms
    start-convert2-4: 55.30810546875ms
    start-convert3-4: 51.42578125ms
    start-convert1-5: 144.20703125ms
    start-convert2-5: 57.093017578125ms
    start-convert3-5: 51.152099609375ms
    start-convert1-6: 143.78076171875ms
    start-convert2-6: 54.94775390625ms
    start-convert3-6: 51.739013671875ms
    start-convert1-7: 147.794921875ms
    start-convert2-7: 57.3330078125ms
    start-convert3-7: 54.512939453125ms
    start-convert1-8: 148.298095703125ms
    start-convert2-8: 55.76806640625ms
    start-convert3-8: 54.154052734375ms
    start-convert1-9: 153.4873046875ms
    start-convert2-9: 54.783203125ms
    start-convert3-9: 55.839111328125ms
    

    在十次的测试中,第三种方法的成绩最好,其次是第二种方式,但二者差距不大。使用 forEach 的第一种方法性能最差。抽象级别越高的方法,性能越弱。

    完。

    相关文章

      网友评论

          本文标题:[记录]多级数组遍历的几种方式

          本文链接:https://www.haomeiwen.com/subject/ywkewftx.html