数组的常用方法,数组遍历的常用方法

96 阅读12分钟
数组的常用方法
           1. push
               * 语法: 数组.push(数据)
               * 作用: 向数组末尾添加数据
               * 返回值: 追加数据后, 数组最新的长度(length)
     
           2. pop
               * 语法: 数组.pop()
               * 作用: 删除数组最后一条数据
               * 返回值: 被删除的数据
     
           3. unshift
               * 语法: 数组.unshift(数据)
               * 作用: 向数组开头添加数据
               * 返回值: 添加数据后, 数组最新的长度(length)
     
           4. shift
               * 语法: 数组.shift()
               * 作用: 删除数组第一条数据
               * 返回值: 被删除的数据
     
           5. reverse
               * 语法: 数组.reverse()
               * 作用: 反转数组
               * 返回值: 反转后的数组
     
           6. sort
               * 语法1: 数组.sort()
                       * 作用: 会将数据转换为 字符串后, 一位一位的对比
               * 语法2: 数组.sort(function (a, b) {return a - b})
                       * 作用: 会按照数字大小升序排列
               * 语法3: 数组.sort(function (a, b) {return b - a})
                       * 作用: 会按照数字大小降序排列
     
               * 返回值: 排序后的数组
      
           7. splice
               * 语法1: 数组.splice(开始索引, 多少个)
                       * 作用: 截取数组部分内容
               * 语法2: 数组.splice(开始索引, 多少个, 插入的数据1, 插入的数据2, 插入的数据3...)
                       * 作用: 截取数组部分内容, 并插入新的数据
      
               * 返回值: 截取出来的部分内容   组成的 数组
      
           数组的方法 能够改变原数组的 就只有上边说的 78. slice
               * 语法: 数组.slice(开始索引, 结束索引)
               * 参数:
                   + 包前不包后: 包含开始索引位置的数据, 不包含结束索引位置的数据
                   + 不写开始索引, 默认是0; 不写 结束索引, 默认是 数组的length
                   + 参数支持写负数, 表示倒数第几个, 其实就是 length + 负数
               * 作用: 截取数组部分内容
               * 返回值: 截取出来的部分内容组成的新数组
               
           9. concat
               * 语法: 原始数组.concat(数组1, 数组2, ...., 数据1, 数据2, ....)
               * 作用: 进行数据拼接, 把数组...数据之类的小括号里的内容, 拼接在原始数组中
               * 返回值: 拼接好的数组
      
           10. join
               * 语法: 数组.join('连接符')
               * 作用: 使用 "连接符", 把数组内的每一个数据连接成一个字符串 (不写连接符, 默认使用的是 逗号)
               * 返回值: 连接好的字符串

           11. indexOf
               * 语法1: 数组.indexOf(要检查的数据)
                       * 作用: 从前到后(从左到右) 检查该数据第一次在该数组内出现 索引
               * 语法2: 数组.indexOf(要检查的数据, 开始索引)
                       * 作用: 在开始索引的位置, 按照从左到右的顺序, 检查该数据第一次在该数组内出现的 索引
               * 返回值: 找到数据的情况下, 会将该数据第一次出现的下标(索引)返回
                           没找到的情况下, 会直接返回一个 -1

               * 备注: 开始索引不写的时候 默认是0

           12. lastIndexOf
               * 语法1: 数组.lastIndexOf(要检查的数据)
                       * 作用: 从后向前(从右向左), 检查该数据第一次在该数组内出现的 索引
               * 语法2: 数组.lastIndexOf(要检查的数据, 开始索引)
                       * 作用: 在开始索引的位置, 按照从右向左的顺序, 检查该数据第一次在该数组内出现的 索引
               * 返回值: 找到数据的情况下, 返回第一次出现的下标(索引)
                           没找到的情况下, 直接返回一个 -1
实践
     var arr = [1, 2, 3]
     console.log('原始数组: ', arr)

     1. push
         var len = arr.push(500)
         console.log(len)    // 4
         console.log(arr)    // [1, 2, 3, 500]

     2. pop
         var po = arr.pop()
         console.log(po)     // 3
         console.log(arr)    // [1, 2]

     3. unshift
         var len = arr.unshift(666)
         console.log(len)    // 4
         console.log(arr)    // [666, 1, 2, 3]

     4. shift
         var st = arr.shift()
         console.log(st)     // 1
         console.log(arr)    // [2, 3]

     5. reverse
         var newArr = arr.reverse()
         console.log('newArr: ', newArr)
         console.log('arr: ', arr)


     6. sort
         var arr = [100, 101, 200, 10, '999', 'qwe', '123abc']
         console.log('原始数组: ', arr)

         var newArr = arr.sort()
         console.log('newArr', newArr)
         console.log('arr', arr)

         var newArr = arr.sort(function (a, b) {return a - b})
         console.log('newArr', newArr)
         console.log('arr', arr)

         var newArr = arr.sort(function (a, b) { return b - a })
         console.log('newArr', newArr)
         console.log('arr', arr)

     7. splice
         var arr = [1, 2, 3, 4, 5, 6, 7, 8, 9]
         //         0  1  2  3  4  5  6  7  8
         console.log('原始数组: ', arr)

     7.1
         var newArr = arr.splice(3, 4)   // 从 下标3 开始截取, 截取 4 个 成员/数据
         console.log('newArr', newArr)   // [4, 5, 6, 7]
         console.log('arr', arr)         // [1, 2, 3, 8, 9]

     7.2
         var newArr = arr.splice(2, 3, '数据1', '数据2', '数据3', '数据4', '数据5')  // 不管插入多少个数据, 都是从下标2开始的
         console.log('newArr', newArr)
         console.log('arr', arr)


     8. slice
         var arr = [1, 2, 3, 4, 5, 6, 7, 8, 9]
                 0  1  2  3  4  5  6  7  8
         console.log('原始数组: ', arr)

         var newArr = arr.slice(3, 4)    // 从 下标3 开始截取, 截取到 下标4
         console.log('newArr', newArr)   // [4]
         console.log('arr', arr)

         var newArr = arr.slice(5)   // 不写 结束索引, 相当于 写了数组.length, 所以这里相当于写了 slice(5, arr.length)
         console.log(newArr) // [6, 7, 8, 9]


           此时 开始索引与结束索引都没有填写,  那么 开始索引相当于是写了一个 0,    结束索引相当于写了 数组.length

               arr.slice()     相当于写了      arr.slice(0, arr.length)

         var newArr = arr.slice()
         console.log(newArr)

         var newArr = arr.slice(3, -2)
         console.log(newArr) // [4, 5, 6, 7]

           arr.slice(3, -2)
               slice 这个方法 允许写 负数

               写负数的时候 就相当于写了 length + 负数

               arr.slice(3, -2)    ->      arr.slice(3, arr.length + (-2))     -> arr.slice(3, arr.length - 2)
                                                                               -> arr.slice(3, 9 - 2)
                                                                               -> arr.slice(3, 7)

     9. concat
         var newArr = arr.concat([4, 5, 6], [10, 20], ['a', 'b', 'c'], 'qwer')
         console.log('newArr', newArr)   // [1, 2, 3, 4, 5, 6, 10, 20, 'a', 'b', 'c', 'qwer']
         console.log('arr', arr)

     10. join
         var newArr = arr.join() // 不传递连接符, 默认使用的是 逗号连接
         var newArr = arr.join('!')  // 使用 ! 将数组内的所有数据拼接成一个 字符串
         console.log(newArr)

     11. indexOf
         var num = arr.indexOf(100) // 此时要检查的数据是 数字100, 但是数组中并没有出现过 数字 100, 所以返回值应该是 -1
         var num = arr.indexOf(0) // 此时要检查的数据是 数字0, 数字0按照从左到右的顺序, 第一次出现的下标为 6, 所以返回值应该是 6
         var num = arr.indexOf(1) // 此时要检查的数据是 数字1, 数字1按照从左到右的顺序, 第一次出现的下标为 0, 所以返回值应该是 0

         var num = arr.indexOf(1, 3) // 此时要检查的数据是 数字1, 但是是从下标3的位置开始按照从左往右的顺序查找, 因为后续并没有数字1, 所以此处应该返回 -1
         console.log(num)

     12. lastIndexOf
         var num = arr.lastIndexOf(3)    // 此时按照从右向左的顺序查找, 发现第一次出现的位置是 下标 5 的位置
         var num = arr.lastIndexOf(3, 2) // 此时在下标2的位置按照从右向左的顺序查找, 但是此时在数组中后续的位置并没有出现数字3, 所以按照规则, 应该返回 -1
         console.log(num)
数组遍历的常用方法
       1. forEach
           * 语法: 数组.forEach(function (item, index, origin) {})
                   * item: 数组的每一项 的值
                   * index: 数组的每一项 对应的下标
                   * origin: 原始数组  (了解即可, 一般没人用)
           * 作用: 遍历数组
           * 返回值: 该方法永远没有返回值 (undefined)
      
       2. map
           * 语法: 数组.map(function (item, index, origin) {})     三个参数的意义与 forEach 相同
           * 作用: 映射数组
           * 返回值: 返回一个和原数组长度相同的数组, 但是内部数据可以经过我们的映射加工
           * 映射加工: 就是在函数内 以 return 的形式书写
      
       有一道面试题: 数组常用的遍历方法中, 有一个forEach 和 一个 map, 这两个方法有什么区别?
               1. forEach 的作用是用来遍历数组, 而 map 的作用是用来映射数组
               2. forEach 没有返回值, 而 map 是可以有返回值的
      
       3. filter
           * 语法: 数组.filter(function (item, index, origin) {})      三个参数的意义与 forEach 相同
           * 作用: 过滤数组
           * 返回值: 返回一个新数组, 内部存储的是原始数组过滤出来的部分内容
           * 过滤条件: 过滤条件以 return 的形式书写
      
       4. find
           * 语法: 数组.find(function (item, index, origin) {})        三个参数的意义 与 forEach 相同
           * 作用: 在数组内查找满足条件的第一项
           * 返回值: 找到的数据, 如果没找到返回的是 undefined
           * 查找条件以 return 的形式书写
      
       5. findIndex
           * 语法: 数组.findIndex(function (item, index, origin) {})       三个参数的意义 与 forEach 相同
           * 作用: 在数组内查找满足条件的第一项 的下标
           * 返回值: 找到的数据 的下标, 如果没找到返回的是 -1
           * 查找条件以 return 的形式书写
      
       6. some
           * 语法: 数组.some(function (item, index, origin) {})            三个参数的意义 与 forEach 相同
           * 作用: 判断数组内是否有一个满足条件
           * 返回值: 一个布尔值    true/false
           * 判断条件以 return 的形式书写
      
       7. every
           * 语法: 数组.every(function (item, index, origin) {})            三个参数的意义 与 forEach 相同
           * 作用: 判断数组内是否全都满足条件
           * 返回值: 一个布尔值    true/false
           * 判断条件以 return 的形式书写
      
       8. reduce
           * 语法: 数组.reduce(function (prev, item, index, origin) {}, init)
               * prev: 表示初始值或者上一次的运算结果
               * item: 表示数组的每一项 的值
               * index: 表示数组的每一项 的下标(索引)
               * origin: 原始数组
           * 作用: 用来实现叠加效果
           * 返回值: 最终叠加的结果
           * 注意: 
                   + 叠加条件以 return 的形式书写
                   + prev 第一次的值, 如果你传递了 init, 就是 init 的值, 如果没有传递 init, 那么就是 数组[0] 的值
                   + 如果传递了 init, 循环执行 数组.length 次, 如果没有传递 init, 循环执行 数组.length - 1
实践
     var arr = [100, 200, 300, 400, 500, 600]
     console.log('原始数组: ', arr)

     1. forEach
         arr.forEach(function (item, index, origin) {
             console.log(item, index)
             console.log(origin)
         })

     2. map
         var newArr = arr.map(function (item, index, origin) {
             // console.log(item, index, origin)
             return item * 2
         })
         var newArr = arr.map(function (item) {
             return item * 2
         })
         console.log('映射出来的数组: ', newArr)

     3. filter
         var newArr = arr.filter(function (item, index, origin) {
             return item > 350   // 过滤数组的内容, 只留下 item 大于 350 的成员
         })
         console.log(newArr)

     4. find
         var newArr1 = arr.find(function (item, index, origin) {
             return item > 3500   // 在数组中查找第一个符合条件的成员
         })
         console.log(newArr1)

     5. findIndex
         var newArr2 = arr.findIndex(function (item, index, origin) {
             return item > 3500
         })
         console.log(newArr2)


         var arr = [1, 2, 3, 4, 5, 6, 7, 8, 9]
         console.log('原始数组: ', arr)

     6. some
         var bo1 = arr.some(function (item, index, origin) {
             // return item % 2 === 0   // 判断数组内是否有  一个  满足条件的
             return item > 500   // 判断数组内是否有 一个 满足条件的
         })
         console.log(bo1)    // true / false

     7. every
         var bo2 = arr.every(function (item, index, origin) {
             // return item % 2 === 0   // 判断数组内 是否  全都    满足条件
             return item > 0     // 判断数组内 是否  全都    满足条件
         })
         console.log(bo2)

         var arr = [1, 2, 3, 4]
         console.log('原始数组: ', arr)
     8. reduce

         var str = arr.reduce(function (prev, item, index, origin) {
             return prev + item
         }, 0)
         console.log(str)    // 10

           在 第 1 轮执行的时候
                   prev === 0  (因为我使用 reduce 方法的时候传递了 第二个参数, 默认给的值为 0)
                   item === 1  他的值就是数组第一项的值
                       在第一轮代码执行的时候, 运行了 return prev + item, 这个结果 会传递给 第二轮循环开始的时候的 prev

           在 第 2 轮执行的时候
                   prev === 1  (因为上一轮执行了 prev + item   的到的值是 1)
                   item === 2  因为是第二轮循环, 所以他的值就是数组第二个元素的值
                       在第二轮代码执行的时候, 运行了 return prev + item,  这个结果会传递给 第三轮循环开始的时候的 prev

           在 第 3 轮执行的时候
                   prev === 3  (因为上一轮执行了 prev + item 得到的值是 3)
                   item === 3  因为是第三轮循环, 所以他的值就是数组第三个元素的值
                       在第三轮代码执行的时候, 运行了 return prev + item, 这个结果会传递给 第四轮循环开始的时候的 prev

           在 第 4 轮执行的时候
                   prev === 6  (因为上一轮执行了 prev + item 得到的值是 6)
                   item === 4  因为是第四轮循环, 所以他的值就是数组第四个元素的值
                       在第四轮代码执行的时候, 运行了 return prev + item, 这个结果会传递给 第五轮循环开始的时候的 prev

           因为后续数组没有元素了, 所以循环到此结束, 然后将 最后一轮 prev 的值 return 出去, 外部可以使用一个变量去接收


         var str = arr.reduce(function (prev, item, index, origin) {
             return prev + item
         })
         console.log(str)    // 10

           第 1 轮
               prev === 1  (因为没传递 init, 所以 prev 第一次的值是数组下标0位置上的值)
               item === 2  (因为没传递 init, 所以 prev 是 下标[0] 的值, 然后 item 就拿到了 下标[1] 的值)
                   第 1 轮 运行代码 return prev + item     这个结果会传递给 下一轮循环开始时的 prev

           第 2 轮
               prev === 3  (因为上一轮执行了 prev + item 得到的值 3)
               item === 3  (因为上一轮item的值是[1], 所以本轮的值是 [2])
                   第 2 轮 运行代码 return prev + item     这个结果会传递给 下一轮循环开始时的 prev

           第 3 轮
               prev === 6  (因为上一轮执行了 prev + item 得到的值 6)
               item === 4  (因为上一轮item的值是[2], 所以本轮的值是 [3])
                   第 3 轮 运行代码 return prev + item     这个结果会传递给 下一轮循环开始是的 prev

           因为后续数组没有元素了, 所以循环到此结束, 然后将最后一轮 prev 的值 return 出去, 外部可以使用一个变量去接收



        var arr = [100, 200, 150, 300]
        //          0    1    2    3

        var str = arr.reduce(function (prev, item, index, origin) {
            return prev + item
        })
        console.log(str)    // 750


           第 1 轮
               prev === 100      (因为没有传递 init, 所以 prev 第一次的值是数组 下标 0 的值)
               item === 200          (因为没有传递 init, 所以 prev 的值是 [0], 那么 item 的值就是 [1])
                   执行代码 return prev + item

           第 2 轮
               prev === 300       (因为 上一轮执行了 prev + item 得到的值 300 )
               item === 150           (因为上一轮item的值是[1], 所以这一轮是[2])
                   执行代码 return prev + item

           第 3 轮
               prev === 450       (因为上一轮执行了 prev + item 得到的值 450)
               item === 300          因为上一轮item的值是 [2], 所以这一轮是[3]
                   执行代码 return prev + item

           后续数组没有元素了, 循环到此结束, 最终的 prev === 750, 然后将这个 750 return 出去