美文网首页
#hello,JS:06-4 ES5 数组拓展

#hello,JS:06-4 ES5 数组拓展

作者: 饥人谷_远方 | 来源:发表于2018-08-11 11:37 被阅读0次

    一、针对Array对象做了大幅拓展

    1、Array.isArray(obj)

    用于判断一个变量(或对象)是否为数组

    如:

    Array.isArray([])
    // true
    
     Array.isArray({})
    // false
    

    2、.indexOf(element) / .lastIndexOf(element)

    用于如何判断在一个数组中找到所看到的一个值、数字,或变量是否存在

    (1)ES3的做法:

             var arr =  [3,  4,  'hello'  ,'wangxiaoqin'] 
    // undefined 
              function  hasWord(arr,item){  for(var i=0; i<arr.length; i++){  
                      if(arr[i]  === item)
                      return  true
      }  
    return  false 
     } 
     // undefined 
    hasWord(arr,'wangxiaoqin') 
    // true  
    hasWord(arr,'helloo')  
    // false
    

    (2)ES5的拓展做法

    var arr =  [3,  4,  'hello'  ,'wangxiaoqin'] 
    //  undefined
    arr.indexOf('wangxiaoqin') 
    //  3 
    arr.indexOf('wanxiaoqin')  
    // -1  //写了一个不存在的,直接输出-1
    

    总结:
    那么,依此可以得出,-1也可以作为判断某对象是否存在于该数组

    3、.forEach(element,index,arrary)

    遍历一个数组,可以使用for循环;也可以数组自带的.forEach

    var arr =  [3,  4,  'hello'  ,'wangxiaoqin'] 
    //  undefined
    arr
     -->  (4)  [3,  4,  "hello",  "wangxiaoqin"] 
                arr.forEach(function(){ 
                       console.log(arguments)  
                 }) 
     -->Arguments(3)  [3,  0,  Array(4), 
          Arguments(3)  [4,  1,  Array(4),  
          Arguments(3)  ["hello",  2,  Array(4),  
         Arguments(3)  ["wangxiaoqin",  3,  Array(4),  
    

    图:

    image
    接着,可以使用.forEach遍历该数组
    arr.forEach(function(value,index){  //value指数组中的元素,index指数组中的下标 
                  console.log(''+value+value) 
                 })  
     -->33  
          44 
          hellohello
         wangxiaoqinwangxiaoqin
     //undefined
    

    4、.every(function(element, index, array))

    用于满足该数组中函数设定的某个条件,函数返回的是一个布尔值
    满足条件:

    • every是所有函数的每个回调函数都返回true的时候才会返回true,当遇到false的时候终止执行,返回false
    • some函数是“存在”有一个回调函数返回true的时候终止执行并返回true,否则返回false
      如:
    [3,4,-1,0,5].every(function(val){ 
                return val>0?true:false  //使用三目运算符 === if...else
      })  
    //  false
    

    .some(function(element, index, array)) 只要有一个符合,那就返回true;反之,则..

    5、.map(function(element))

    对数组中每一元素进行处理,函数返回值组成一个新数组返回,新数组索引结构和原数组一致,原数组保持不变。

    var arr2 =  [1,  2,  3,  4,  5,  6].map(function(val){ 
                  return val*val 
            }) 
    // undefined
    arr2 
    //  (6)  [1,  4,  9,  16,  25,  36]
    

    6、.filter(function(element))

    数组的过滤。

    注:

    产生新数组,原数组保持不变,如:

    var arr=[3,  5,  6,  -1,  -2,  -3] 
    //  undefined
    arr.filter(function(val){  
             return val>0  
       }) 
    //  (3)  [3,  5,  6]  //产生新数组 
    arr 
    //  (6)  [3,  5,  6,  -1,  -2,  -3]  //原数组不变  
    
    /* 所以,我们需要为新数组赋新变量 */  
    var arr2 = arr.filter(function(val){ 
                return val>0 
     })  
    // undefined
    arr2
    //  (3)  [3,  5,  6]  
    
    /* 如需过滤出里面的负数 */  
    var arr3 = arr.filter(function(val){  
                 return val <0 
             })  
    // undefined
    arr3 
    //  (3)  [-1,  -2,  -3]
    

    再如:

    var students =  [
             { 
              name:'ad',
              age:10  
              }, 
             { 
             name:'bb',
             age:20 
            },  
            { 
             name:'ca', 
             age:8 
             }, 
             { 
             name:'ce', 
            age:5 
             },  
    ]  
    
    /* 假设过滤出数组里年纪大于18岁的 */ 
    var age18 =
            students.filter(function(students){ 
                   return students.age >  18  
                 }) 
                   console.log(age18) 
    
        --> [[object Object]  {
                    age:  20,
                    name:  "bb"hui
                   }
         ] 
    
    /* 假设过滤出数组里姓名里带有“c” */
     var namehasc = 
                students.filter(function(students){  
                   return students.name.indexOf('c')>-1
             }) 
                  console.log(namehasc) 
     -->[[object Object]  { 
                         age:  8, 
                         name:  "ca" 
              },  [object Object]  { 
                     age:  5, 
                    name:  "ce" 
        }]
    

    以此,可以通过过滤可进行排序、查找、单独的处理

    7、.reduce(function(v1, v2), value)

    两元素(或参数)执行操作,数组元素返回组合成一个值,遍历数组,继续和数组中 其他元素组合,最终得出结果。代码如下:

    var arr =  [3,  4,  5]  
    --> undefined
    arr.reduce(function(v1,v2){  
               return v1 + v2
              })  
      -->  12  //7+5 
    arr.reduce(function(v1,v2){  
               return v1 * v2
             })  
    -->  60  //12*5 
    
    /* 使用初始值  .reduce(function(v1, v2), value)  value为初始值 */
    arr.reduce(function(v1,v2){
                  return v1 + v2 },100)  
        --> 112    
    
    //100(v1)+3(v2)+4+5  
    //103(v1)+4(v2)+5
     以此类推
    

    二、学习

    1、手写reduce功能

    A、先补充一些基本JS知识,

    假设:想要克隆一个与arr完全一样的arr2,但二者互不相干,如何处理?
    通过使用concat方法,一个数组arr拼接另一个数组,然后得到一个新的数组arr2。即通过concat获得一个新数组,拼接的原数组保持不变。实现一个深拷贝。

    注:[ ]空数组也是一个数组

    arr =  [1,2,3]  
    // [1,  2,  3] 
    arr2 = arr.concat([])  
    // [1,  2,  3] 
    arr2
    // [1,  2,  3]  
    
    /* 测试一下是否二者有关联 */
     arr2[0]  =  100  
    // 100
     arr 
    //  [1,  2,  3] 
    arr2
    //  [100,  2,  3]
    

    B、手写一个reduce功能

    function  reduce(arr, fn, initValue){ 
                   var arr2 = arr   //===[3, 4, 5, 6]  
                     while(arr2.length >  1)
                      }  
    //第2:如何是实现reduce?计划通过处理arr2 = [3, 4, 5, 6]的v1,v2, 通过function(v1,v2){return v1+v2}处理,依次循环得出结果 
    
       var arr =  [3,  4,  5,  6]  
      var result =  reduce(arr,  function(v1,v2){  
                      return v1+v2 //第1:通过此遍历arr数组
       },10)
    

    取消初始值去做:

    function  reduce(arr, fn){ 
                 var arr2 = arr   //===[3, 4, 5, 6] 
                      while(arr2.length >  1){
                        console.log(arr2) 
                        arr2.splice(0,2,fn(arr2[0],arr2[1])) 
                         }    
                   return arr2[0]  
                 }  //第3:while(arr2.length > 1)  相当于设置一个条件:当这个数组有两个以上的值时,  
    //第4:arr2 === arr用fn函数进行处理,v1+v2相加替换成一个结果, 使用splice(位数,个数,替换的结果),依次类推得出arr2 === arr的结果  
    
                   var arr =  [3,  4,  5,  6]  
                          //[7,5,6]  
                         //[12,6]  
                        //[18]  
                  var result =  reduce(arr,  function(v1,v2){ 
                                 return v1+v2
                           })
                      console.log(result)  
                
            //输出结果  
                  -->[3,  4,  5,  6]  
                       [7,  5,  6] 
                       [12,  6]  
                       18
    

    图:

    image
    但是,这里有个问题,就是arr2===arr,却没有实现二者互不相关。如何处理?如图:
    image
    可以通过: 原始数组.concat([])组合成一个新数组,且原数组与之无关。如图:
    image

    添加初始值之后,该如何做呢?

    function  reduce(arr, fn,initValue){ 
                      var arr2 = arr.concat([])  //===[3, 4, 5, 6]  
                      if(initValue !== undefined){  //这里注意 === 会出现报错 
                      arr2.unshift(initValue)  
                    }  
    //不等于undefined,表示用户传递了这个initValue参数  
                    
                       while(arr2.length >  1){
                                  console.log(arr2) 
                                  arr2.splice(0,2,fn(arr2[0],arr2[1]))  
                           } 
                             return arr2[0]  
                     }  
          
                    var arr =  [3,  4,  5,  6]  
                    var result =  reduce(arr,  function(v1,v2){  
                                 return v1 + v2 },10) 
                                 console.log(result)  
                  
    //输出值: 
              -->  [10,  3,  4,  5,  6] 
                     [13,  4,  5,  6] 
                     [17,  5,  6]  
                      [22,  6]  
                      28  
    

    图:


    image

    或者减少代码量,采用三目运算符的方法来设置初始值:

    function  reduce(arr, fn,initValue){ 
                  var arr2 =
                  (initValue !== undefined?[]:[initValue]).concat(arr)  
                  while(arr2.length >  1){ 
                      console.log(arr2) 
                      arr2.splice(0,2,fn(arr2[0],arr2[1]))
                 }  
                   return arr2[0] 
           }  
       
          var arr =  [3,  4,  5,  6]  
          var result =  reduce(arr,  function(v1,v2){ 
                      return v1 + v2 },10) 
                      console.log(result)  
    
    //输出值  
     -->  [3,  4,  5,  6] 
             [7,  5,  6]
             [12,  6]  
             18
    

    图:


    image

    2、将一个数组拍平

    对一个无限次嵌套的数组进行拍平,如何处理?

    例子1:这道题也可以作为一个初级JS的思考,每次不会做的话,先从这道题的基本思考方式来看

    var arr =  [3,  ['4,5',7,[1]],  [2,10]  ]  
               function  flat(){ 
               }  //重点解决这一块的逻辑,即最终返回一个新的数组  
           var arr2 =  flat(arr) 
            console.log(arr2) 
     ---------------------------------------------------- 
    
     var arr =  [3,  ['4,5',7,[1]],  [2,10]  ]  
                function  flat(arr){  
                      var arr2 =  [] 
                      arr.forEach(function(val){  
                       if(Array.isArray(val)){ 
                        arr2 =arr2.concat(flat(val)) 
                  }else{ 
                     arr2.push(val) 
                    }  
               }) 
              return arr2//不是数组的话就返回  } 
    
     /*   flat(arr)就是将一个数组拍平,变成一个普通数组,对arr里进行判断,  如果不是个数组(如3),则放在 var arr2 = []里的空数组里,  如果是数组的,即 ['4,5',7,[1]],则把其放在这个arr.forEach(function(val){})数组里执行,则  重点解决函数这一块的逻辑  :
    1、定义一个要返回的数组arr2  
    2、遍历原始数组arr,且用函数遍历arr的每一项  
    2.1 if判断是否为数组,采用Array.isArray判断。 若是数组,要处理嵌套数组,再次调用函数,将嵌套函数“拍平”,用递归法一一验证,最后得出结果  
    2.2 else如果不是数组,直接push在arr=[]里  */
    
     var arr2 =  flat(arr) console.log(arr2)  
    
    //输出结果
    --> [3, "4,5", 7, 1, 2, 10]
    

    例子2:
    实现一个flatten函数,将一个嵌套多层的数组arry(数组)(嵌套可以是任何层数)转换成只有一层的数组,数组中元素仅基本类型的元素或数组,不存在循环引用的情况。如:

       flatten([1,[2],[3,[[4]]])=> [1,2,3,4]
    
    var arr =  [3,[2,-4,[5,7]],-3,['aa',[['bb']]]]  
    var arr2 =  flatten2(arr) 
    console.log(arr2)  
    
    /* 方法1: */
                  function  flatten(arr){ 
                         var newArr =  []  
                          function  _flat(arr){ 
                                 arr.forEach(val=>{  //对数组的每一项进行一个遍历   val=>,为匿名函数  
                                   if(Array.isArray(val)){ 
                                          _flat(val) 
                                }else{ 
                                     newArr.push(val) 
                                   }  
                                }) 
                           } 
                          _flat(arr)  
                             return newArr }  
    
    /* 方法2: */ 
    
            function  flatten2(arr){  
                      return arr.reduce(function(initArr,currentArr){  
                      return initArr.concat(Array.isArray(currentArr)?flatten2(currentArr):currentArr) 
                       },[])  
                  }  
    
    /*不是数组的话,就concat;如果是数组,则通过再次调用```flatten2(Arr)```拍平当前数组```flatten2(currentArr)``` */
    

    相关文章

      网友评论

          本文标题:#hello,JS:06-4 ES5 数组拓展

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