遍历数组的一些简单方法

185 阅读11分钟

1 forEach

     *      语法: 数组.forEach(function (item, index, origin) { 遍历数组后你想要做的事 })
     *              参数:
     *                  item: 数组中每一个元素
     *                  index: 每一个元素对应的下标
     *                  origin: 原数组                  很少有人使用 第三个参数
     *      作用:   根据数组的元素内容, 循环遍历数组, 拿到数组的每一项
     *      返回值: 没有返回值
     *      语义: 遍历数组
     *
         
         var arr=["a","b","c",,"d","e","f"];

         // forEach 不遍历空元素
         arr.forEach(function(value,index){
             console.log(value,index);
           })


forEach 不遍历空元素    "c""d"  之间的遍历不出来                

image.png

1.1 forEach 重构

    var arr=["a","b","c",,"d","e","f"];
     function arrayForEach(array,callback){
         for(var i=0;i<array.length;i++){
            // if(i in array) 空元素是false
            if(i in array)   callback(array[i],i,array);
         }
    }
 

    arrayForEach(arr,function(value,index,array){
        console.log(value,index,array);
    })

1.2 forEach 修改数组

   var arr=["a","b","c","d","e"];
    参数array和数组arr的引用地址相同,是同一个数组,所以修改这个数组对应的下标的元素值是可以的
    arr.forEach(function(item,index,array){
        if(item==="c") array[index]=0;
    })
    console.log(arr);



    var arr=[
        {id:1001,name:"商品1",price:2190,num:1},
        {id:1002,name:"商品2",price:1234,num:4},
        {id:1003,name:"商品3",price:1456,num:3},
        {id:1004,name:"商品4",price:1890,num:2},
        {id:1005,name:"商品5",price:2098,num:5},
    ]

    arr.forEach(function(item){
        item.total=item.price*item.num;
    })

    这样操作都会改变原数组中的对象结构 
    console.log(arr);
        forEach如果要遍历数组,数组里的元素是非引用类型,
        修改元素时需要通过第三个参数array修改
        数组里的元素是引用类型,直接可以修改forEach遍历时第一个参数value的值
        修改每个
        引用对象的属性,可以删除属性,添加属性,修改属性 
        
   // 使用抛出异常,try,catch捕获异常处理可以停止forEach的循环
    var arr=[1,2,3,4,5];
    try{
        arr.forEach(function(item){
            if(item>3) throw new Error("aa");
            console.log(item);
        })

    }catch(e){

    }      

2 map

     *      语法: 数组.map(function (item, index, origin) { 遍历数组后你想要做的事 })
     *              参数:
     *                  item: 数组中每一个元素
     *                  index: 每一个元素对应的下标
     *                  origin: 原数组                  很少有人使用 第三个参数
     
           // map 具备与forEach相同的特征
           // map会返回一个新数组,map遍历执行回调函数时,
              必须每次执行回调函数中使用return返回一个结果
           // 而这个新数组就是每次使用return返回值组成的新数组
           // map返回的新数组的长度与原数组长度完全一致,
              如果遍历时没有使用return返回值,
              则对应的新数组中下标值是undefined     
     *      语义: 映射数组    return item * 2 或 加减乘除取余都可以,映射数组作用与数字
     
       var arr=[4,5,6,7,8];
 
    var arr1=arr.map(function(value){
         return value+10;
      })

     console.log(arr1);// [14, 15, 16, 17, 18]
     
                     var arr=[
                    {id:1001,name:"商品1",price:2190,num:1},
                    {id:1002,name:"商品2",price:1234,num:4},
                    {id:1003,name:"商品3",price:1456,num:3},
                    {id:1004,name:"商品4",price:1890,num:2},
                    {id:1005,name:"商品5",price:2098,num:5},
                ]

                // 使用map可以产生新的对象,与原数组中引用元素无关
                var arr1=arr.map(function(item){
                    return {
                        id:item.id,
                        name:item.name,
                        price:item.price
                    }
                })

                arr[0].price=3190;
                console.log(arr1);

2.1 map 重构

          function arrayMap(array,callback){
            var arr1=[];
            for(var i=0;i<array.length;i++){
                    //  arr1[i] 因为函数callback的返回结果是1 的关系数组arr1不断填入1
                if(i in array) arr1[i]=callback(array[i],i,array);
               
            }
            // arrayMap(array,callback) 运算返回结果 是数组arr1
          
            return arr1;
        }


        var arr=["a","b","c","d","e"];

      var arr1=arrayMap(arr,function(value,index,array){
            // 调动函数没调动一次 给函数callback的返回结果是1
          
            return 1;
        })

        console.log(arr1); //  [1, 1, 1, 1, 1]

3. filter

     *      语法: 数组.filter(function (item, index, origin) {})
     *      作用: 过滤数组
     *      返回值: 过滤出来的内容组成的一个新数组
     *
            var arr = [1, 2, 3, 4, 5, 6, 7, 8, 9, 10]
            arr = arr.filter(function (item) {
                return item % 2 === 0
                // return item % 3 === 0
                // return item >= 5
            })
            console.log('方法使用后的数组: ', arr)
            
            
        var arr=[
        {id:1001,name:"商品1",price:1357},
        {id:1002,name:"商品2",price:3254},
        {id:1003,name:"商品3",price:2956},
        {id:1004,name:"商品4",price:1845},
        {id:1005,name:"商品5",price:1092},
        {id:1006,name:"商品6",price:6000},
    ]

    var id=1003
    // 要求将id是1003的元素放在这个数组的最前面
    
   解法 
     var arr1=arr.filter(function(item
                         // id是变量
        return item.id===id;
    }).concat(arr.filter(function(item){
        return item.id!==id;
    }))
            

4. find

     *      语法: 数组.find(function (item, index, origin) {})
     *      作用: 去数组中查找内容 (可查找引用数据类型)
     *      返回值: 查找到的数据, 如果找不到那么返回 undefined
     *      注意:仅返回第一个遇到的元素
            var arr = [1, 2, 12, 4, 5, 6, 7, 8, 9, 10]

            var ret = arr.find(function (item) {
                // return item % 2 === 0
                return item >2
            })

                console.log(ret)
                
            var arr=[
                {id:1001,name:"商品1",price:1357},
                {id:1002,name:"商品2",price:3254},
                {id:1003,name:"商品3",price:2956},
                {id:1004,name:"商品4",price:1845},
                {id:1005,name:"商品5",price:1092},
                {id:1003,name:"商品3",price:2956},
                {id:1006,name:"商品6",price:6000},
            ]              
    // find 将查找到的某个引用类型属性判断为值的这个引用对象元素返回,
                                   仅返回第一个遇到的元素
     var item=arr.find(function(value){
         return value.id===1003;
     })
     console.log(item);// {id: 1003, name: '商品3', price: 2956}
   
   
    // 将所有满足条件的元素放在数组中都返回出来
     var arr=arr.filter(function(item){
         return item.id===1003;
     })
     console.log(arr);
     // 在对象数组中,如果要查找其中某一个得到这个被查到元素,使用find
    // 如果在数组中要查找所有满足条件的,使用filter,得到一个数组

4.1 findLast

           // 从后向前查找(可查找引用数据类型)如果找不到那么返回 undefined
            var item=arr.findLast(function(value){
                return value.id===1003;
            })
            console.log(item);

5. findIndex

     *      语法: 数组.findIndex(function (item, index, origin) {})
     *      作用: 去数组中从前向后查找内容(可查找引用数据类型)
     *      返回值: 查找到的数据对应的下标, 如果找不到那么返回 -1
     *       注意:只能查找到第一个下标 
             var arr = [1, 2,12,3, 4, 5, 6, 7, 8, 9, 10]

            var res = arr.findIndex(function (item) {
                return item >= 7
            })

5.1 findLastIndex

  从后向前查找(可查找引用数据类型)如果找不到那么返回 -1
var index=arr.findLastIndex(function(item){
    // 遍历对象,判断对象中某个属性等于什么值,返回这个属性值相等遇到的第一个元素的下标
    return item.id===1003;
})
console.log(index);

6. every

     *      语法: 数组.every(function (item, index, origin) {})
     *      作用: 判断数组中是否全都符合条件
     *      返回值: 符合条件_true;  否则为_false
     *
            var arr = [1, 2, 3, 4, 5]
            var res = arr.every(function (item) {
                // return item % 2 === 0
                return item > 0
            })

            console.log(res)
         

7. some

     *      语法: 数组.some(function (item, index, origin) {})
     *      作用: 判断数组中是否有符合条件的元素 (有一个符合条件的就行)
     *      返回值: 符合条件_true;  否则为_false
     *
            var arr = [1, 2, 3, 4, 5]
            var res = arr.some(function (item) {
                // return item % 2 === 0
                return item > 500
            })
            console.log(res)

8. reduce

     *      语法: 数组.reduce(function (prev, item, index, origin) {}, init)
     *
     *          参数1: function (prev, item, index, origin) {}
     *                  1. item, index, origin  和之前的含义一样
     *                  2. prev:    
     *                       return prev + item   
     *                              如果是第一次执行    =>      如果传递了 init, 那么 prev 就是 init 的值, item为数组[0];
     *                                                          否则 prev 为 数组[0]的值, item 顺延为 数组[1] 的值
     *                              如果是第一次后续的执行      =>      那么 prev 的值就是上一次遍历 return 的结果
     *          参数2: init
     *              - 随意传递一个值即可(数字,字符之类的都行), 只要符合需求
     *
     *      作用: 累加器
     *      返回值: 累加后的结果
     *
    */
   有  init 的值
                var arr = [1, 2, 3, 4, 5]
                //console.log('原数组: ', arr)
                var res = arr.reduce(function (prev, item) {
                    return prev + item
                }, "")
                console.log(res)


    /**
     *  第一次执行
     *
     *      因为传递了 init, 那么函数第一次运行时第一个形参的值就是 init 传递的内容
     *      所以 prev === "",   item 也就顺理成章的是 数组[0]
     *
     *      return prev + item          =>      return "" + arr[0]      =>      
     return "" + 1       => return "1"
     *              注意, 这个一轮运行的 返回值 会给到 下一次循环的第一个参数
     *
     *
     *  第二次运行
     *      return prev + item      =>      return "1" + arr[1]     =>  return "1" + 
     
           2   => return '12'
     *              注意, 这个一轮运行的 返回值 会给到 下一次循环的第一个参数
     *
     *  第 3 次运行
     *      return prev + item      =>      return "12" + arr[2]     =>  return "12"          
           + 3   => return '123'
     *              注意, 这个一轮运行的 返回值 会给到 下一次循环的第一个参数
     *
     *  第 4 次运行
     *      return prev + item      =>      return "123" + arr[3]     =>  return     
       "123" + 4      => return '1234'
     *              注意, 这个一轮运行的 返回值 会给到 下一次循环的第一个参数
     *
     *  第 5 次运行
     *      return prev + item      =>      return "1234" + arr[4]     =>  return 
     "1234" + 5      => return '12345'
     *
     *
     *  注意: 当前案例中, 数组已经全部遍历完毕, 所以第 5 次的 return 会给到 arr.reduce()
    */
    
    
      没 有  init 的值  
       var arr = [1, 2, 3, 4, 5]
                //console.log('原数组: ', arr)
                var res = arr.reduce(function (prev, item) {
                    return prev + item
                })
                console.log(res)
                
   /**
     *  第一次运行
     *      因为没有传递第二个参数 init, 所以 prev 就是 数组[0] 的值, item 就是从 数组[1]
     *          return prev + item          return arr[0] + arr[1]          return 3
     *              注意, 这个一轮运行的 返回值 会给到 下一次循环的第一个参数
     *
     *  第二次运行
     *      return prev + item          return 3 + arr[2]           return 6
     *              注意, 这个一轮运行的 返回值 会给到 下一次循环的第一个参数
     *
     *  第三次运行
     *      return prev + item          return 6 + arr[3]           return 10
     *              注意, 这个一轮运行的 返回值 会给到 下一次循环的第一个参数
     *
     *  第四次运行
     *      return prev + item          return 10 + arr[4]           return 15
     *
     *  注意!!!     此时数组内所有的数据已经遍历完毕了, 此时reduce 不会有下一次执行
     *
     *      所以当前案例中 第四次的运行结果 会给到 arr.reduce()
    */
    
    

利用 reduce, 拼接出 五个 div 标签

       var arr = [1, 2, 3, 4, 5]
     '<div></div><div></div><div></div><div></div><div></div>'
    //  这里没用到item也就是数组的元素,可以删去,一般不用话,也不需要删,
    //  就算删除item代表的循环次数效果还在
    //  item 代表了循环次数也就是数组长度,有init的值,循环下标零开始,循环次数是数组长度,
            没有init的值,循环下标1开始,循环次数是数组长度-1
    //  prev是初始值,必须存在
    
    
            var res = arr.reduce(function (prev, item) {
                return prev + '<div></div>'
    }, "")

               console.log(res)

求随机颜色

  ~~符号向下取整
   // toString(16) 将数值转换为16进制的字符串
    function randomColor(){

  return Array.from({length:6}).reduce((value,item)=>value+  (~~(Math.random()*16)).toString(16),"#")

    }




    var color=randomColor();

    console.log(color)

Array.from()

<input type="checkbox">
<input type="checkbox">
<input type="checkbox">
<input type="checkbox">
<input type="checkbox">

// Array.from();//将迭代器转换为数组 列表、集合转换为数组,返回数组
 var list=document.getElementsByTagName("input");
    
// 转换数组
//    var arr=Array.from(list);//[input, input, input, input, input]



  // 创建一个长度为10的数组,里面的元素是undefined
    var arr = Array.from({ length: 10 });
    console.log(arr);//[undefined, undefined, undefined,
                        undefined, undefined, undefined, 
                        undefined, undefined,
                        undefined, undefined]
 // Array(100) 创建长度为100的空元素数组                      
  var arr =  Array(100)
  console.log(arr); //[empty × 100]
 // Array.from({length:100}) 创造长度为100的,undefined为元素的数组
 
 //利用map 给空数组增加数字
    var arr=Array.from({length:100}).map(function(item,index){
         return index+1;
     })
     console.log(arr);
// Array(100) 创建长度为100的空元素数组,空元素无法遍历 也就 
  var arr= Array(100).map(function(item,index){
         return index+1;
     })
     console.log(arr);

flat 数组扁平化 原数组不改变,返回一个被扁平化的新数组

    就是拆除数组里面元素的数组
    var arr = [    [1, 2, 3, [4, 5, 6, [7, 8, [10, 11], 12, 13], 14], 15],
    16,
    [17, [18, [19, 20, [21, 22, [23, 24]]]]],
  ];
     var arr1= arr.flat();//flat里面不写数字默认深度为1
     console.log(arr1); // [1, 2, 3, Array(5), 15, 16, 17, Array(2)]
     
     
      var arr1= arr.flat(4); // 拆除4层数组框
     console.log(arr1);//[1, 2, 3, 4, 5, 6, 7, 8, 10, 11, 12, 13, 14, 15, 16,
                          17, 18, 19, 20, 21, 22, Array(2)]
          
          
          
            首先传入一个目标深度,准备一个目标的空数组,遍历数组
            ,判断这个元素是数组还是元素,
            如果是元素放入到目标数组
            如果是数组,判断当前深度是否小于目标深度,如果小于目标深度,
            递归重新遍历数组,直到等于或大于目标深度
            将元素放入,如果当前深度大于目标深度
            直接将数组放入到目标数组中

  sourceArray 需要扁平化的原数组
  depth 需要扁平化的深度
  function flat(sourceArray,depth = 1) {
    // 创建一个目标数组空数组
    var targetArray=[]
    // 创建一个用来扁平化的函数
        function flatArray(array,currentDepth=0) {
            //currentDepth 当前深度默认是0
            // 第一次进入这个函数时,array是原数组
            for (var i = 0; i < array.length; i++) {
                // 如果当前这个元素是数组,并且当前深度小于目标深度 当前深度第一次0,
                          目标深度外面传入的4
                if (Array.isArray(array[i]) && currentDepth < depth) {
                    // 这次递归,将这个数组放入到递归函数中作为下一次遍历的数组,
                         并且将当前深度+1放入在递归函数中
                    targetArray = flatArray(array[i],currentDepth+1);
                } else {
                    // 如果不是数组,直接将它push目标数组的尾部
                    targetArray.push(array[i]);
                }
            }
            return targetArray;
        }
    // 执行扁平化函数并且将扁平化后的结果返回给函数外,传入的是需要扁平化原数组
    return flatArray(sourceArray);
  }

  var arr1 = flat(arr,5);//5就是目标深度
  console.log(arr1);
  

flatMap

 // flatMap  只能扁平化一层,还具有map的特征
 
     var arr=[[1,2,3],[4,5,6],[7,8,9]];
       var arr1=arr.flatMap(function(item,index,arr){
            item.push(0);
            return item;
        })
        console.log(arr1)