javascript基础学习冒泡排序等

javascript基础学习

冒泡排序

  1. 意义:是吧一个乱序的数组通过代码执行,排成有序的数组

  2. 准备原始数组

  3. var arr = [ 9, 1, 2, 3, 4, 5, 6, 7, 8 ] // 目的: [ 1, 2, 3, 4, 5, 6, 7, 8, 9 ]
    console.log('原始数组 : ', arr)
    
  4. 冒泡排序, 是若干数组排序算法的一种

  5. 逻辑:

1遍历数组, 两两对比, 把相对较大的数字向后移动
2遍历一遍以后, 得到的结果就是最大的数字一定在最后面
3重复步骤1, 继续比较, 两轮以后, 最大的两个数字一定在最后两个位置
4不管多少个数字, 只要比较总长度 -1 轮, 那么数组就排序完成了

步骤一

交换 [0][1] 位置的数据
    var tmp = arr[0]
    arr[0] = arr[1]
    arr[1] = tmp
    tmp = null
    console.log('交换完毕 : ', arr)

步骤二:

交换 [0][1] 位置的数据
    var tmp = arr[0]
    arr[0] = arr[1]
    arr[1] = tmp
    tmp = null
    console.log('交换完毕 : ', arr)
  1. 问题:如何判断出本轮全是 false

    1就看 if 内的代码是否有执行过
    2因为只有 true 的时候才会执行 if 内的代码
    3如果这一轮之内, if 内的代码从来没有执行过, 那么就是全 false
    4在此之后的所有内容都不需要了

计数排序

  1. 计数排序: 数组排序算法的一种
  • 逻辑:

  • 准备一个新的数组
    => 遍历原始数组, 把原始数字当做新数组的索引向新数组内填充数据
    => 新数组的数据按照计数排列

  • 遍历新数组

    => 把索引在当做数据放进原始数组内
    => 前提: 把原始数组清空

    • 代码

    • 准备一个原始数组

      var origin = [ 9, 3, 100, 6, 4, 100, 1, 9, 8, 7, 2, 2, 5, 100, 3, 32, 55 ]
      console.log('原始数组 : ', origin)
       //准备一个新数组
        var newarr = []
      
      1. 步骤2: 把新数组内的索引, 当做数据还原到 origin 内, 把 新数组内的值, 当做个数插入
        // // 归零 origin
        // origin.length = 0
        // console.log('origin 归零 : ', origin)

      2. for (var i = 0; i < newarr.length; i++) {
            //   // 2-1. 如果当前 [i] 位置没有数据, 那么循环的本次不需要了
              if (!newarr[i]) continue
        
            //   // 2-2. 把有数据位置的索引 i 当做真实数据, 追加到 origin 内
            //   // 问题: 所有的都直接追加吗 ?
            //   //   值为 1 的, 直接追加, 否则的话, 值是多少, 追加多少个
            if (newarr[i] === 1) {
              origin[origin.length] = i
            } else {
            //     // 值是多少, 追加多少个, 循环来追加
            //     // 问题: 循环多少次, 值是多少, 循环多少次
             for (var k = 0; k < newarr[i]; k++) {
                 origin[origin.length] = i
             }
             }
        
              console.log(i)
             }
        
             for (var i = 0; i < newarr.length; i++) {
            //   // 2-1. 如果当前 [i] 位置没有数据, 那么循环的本次不需要了
             if (!newarr[i]) continue
        
            //   // 2-2. 把有数据位置的索引 i 当做真实数据, 追加到 origin 内
            //   // 当前这个索引位置上的值是多少, 就向 origin 内追加多少个当前索引数字
              for (var k = 0; k < newarr[i]; k++) origin[origin.length] = i
             }
        
        
             console.log('排序之后 : ', origin)
        
      3. 计数排序

        var origin = [ 10,20,30,40,50,60,70,10,30,40,50 ]
            var newarr = []
        
            // 1. 把数据当索引
            for (var i = 0; i < origin.length; i++) {
              // origin[i] 就是数据
              newarr[ origin[i] ] ? newarr[ origin[i] ]++ : newarr[ origin[i] ] = 1
            }
        
            // 2. newarr 中的索引当数据
            //    newarr 中的值当多少个
            // 2-1. 清空 origin
            origin.length = 0
            // 2-2. 填充回去
            for (var i = 0; i < newarr.length; i++) {
              // i 表示真实数据
              // newarr[i] 表示有多少个
              if (!newarr[i]) continue
        
              // 填充回去
              // 填充 newarr[i] 个 i
              for (var k = 0; k < newarr[i]; k++) origin[origin.length] = i
            }
        	origin.push([)
            console.log('排序之后 : ', origin)
        
        
        1. / 问题: 如何判断一个数组内有没有某一个索引位置的数据 ?
          // 索引可以访问数组内的数据
          // 如果有该索引位置, 那么就是该索引位置的数据
          // 如果没有该索引位置, 那么就是 undefined
          // 根据我的设置
          // 原先有就是 ++, 原先没有就是 = 1
          // 如果我拿到数组内某一个索引位置是 undefined, 说明之前没有过
          // 只要之前有过, 那么一定是一个正整数
          // console.log(newarr[1])
          // if (newarr[1] === undefined) newarr[1] = 1
          // else newarr[1]++
          // console.log(newarr)

        2. 逻辑

          1.  // 逻辑
                 var origin = [ 2, 3, 2, 6, 5]
                 console.log(origin)
            
                 var newarr = []
                 newarr[2] = 1
                newarr[3] = 1
                newarr[2]++
                newarr[6] = 1
                newarr[5] = 1
            
                 console.log(newarr)
            
                origin = []
            
                 console.log(origin)
            
                origin[origin.length] = 2
                origin[origin.length] = 2
                origin[origin.length] = 3
                origin[origin.length] = 5
                origin[origin.length] = 6
            
                console.log(origin)
            

选择器

  1. 选择排序

    1. 1遍历数组, 找到数组中最小的数字, 和最前面一个数字对调
      2从第二轮开始, 跳过第一个, 剩下的再继续重复步骤
    2. 第 x 轮外层循环控制变量假设里层循环开始对调
      1001[0] 和 [minIndex]
      2112[2] 和 [minIndex]
      3223[3] 和 [minIndex]
    3. 代码

      1. 步骤一
      // 1-1. 遍历找到最小的数字的索引
          // // 假设 [0] 位置数据最小
          var minIndex = 0
          // // 遍历数组进行比较
          for (var i = 1; i < arr.length; i++) {
          //   // 开始比较, 依次把 arr[i] 和 arr[minIndex] 比较
            if (arr[i] < arr[minIndex]) minIndex = i
          // }
          // // 循环完毕以后, minIndex 就是最小数字的索引
          // // 就把 [minIndex] 位置和 [0] 位置的数据进行对调
          // // 问题: 每一次都必须要对调吗 ? 如果 minIndex === 0 不需要对调了
          if (minIndex !== 0) {
            var tmp = arr[0]
            arr[0] = arr[minIndex]
            arr[minIndex] = tmp
            tmp = null
          }
          console.log('排序一次 : ', arr)		
              
          
      
      1. 步骤二

        // 假设 9 个数字, 比较多少轮 ? 8 轮
            for (var j = 0; j < arr.length - 1; j++) {
              // 完整书写步骤1
        
              // 假设
              var minIndex = j
        
              // 里层循环开始
              for (var i = j + 1; i < arr.length; i++) {
                if (arr[i] < arr[minIndex]) minIndex = i
              }
        
              // 对调
              if (j === minIndex) continue
              // 代码执行到这里, 说明 j 和 minIndex 不一样
              var tmp = arr[j]
              arr[j] = arr[minIndex]
              arr[minIndex] = tmp
              tmp = null
            }
        
            console.log('排序之后 : ', arr)
        
        

数组常用方法

  1. 数组常用方法
    + 什么是数组常用方法
    + JS 提供给我们专门用来操作数组的方法
    + 因为数组本身的特性决定了 好加不好去, 不好插入
    + 语法特点: 数组.方法名(参数)
    => 不同的方法, 就是方法名和参数不一样

  2. push()
    => 语法:
    -> 数组.push(数据)
    -> 数组.push(数据, 数据2, 数据3, 数据4, …)
    => 作用: 按照顺序向数组的后面追加你插入的数据
    => 返回值: 追加数据以后, 数组最新的长度

    2. pop()
    => 语法: 数组.pop()
    => 作用: 删除数组的最后一个数据
    => 返回值: 被删除的数据
    
    3. unshift()
    => 语法:
      -> 数组.unshift(数据)
      -> 数组.unshift(数据, 数据2, 数据3, 数据4, ...)
    => 作用: 按照顺序向数组的最前面插入数据
    => 返回值: 插入数据以后, 数组最新的长度
    
    4. shift()
    => 语法: 数组.shift()
    => 作用: 删除数组最前面一个数据
    => 返回值: 被删除的数据
    
  3. var arr = [ ‘hello’, ‘world’, ‘你好’, ‘世界’ ]
    console.log('原始数组 : ', arr)

    // 1. push()
    // 开始追加
    // var res = arr.push(‘新来的’)
    // var res = arr.push(‘新来的’, 100, 200)
    // console.log('追加以后 : ', arr)
    // console.log('返回值 : ', res)

    // 2. pop()
    // 开始删除
    // var res = arr.pop()
    // console.log('删除以后 : ', arr)
    // console.log('返回值 : ', res)

    // 3. unshift()
    // var res = arr.unshift(‘新来的’)
    // var res = arr.unshift(‘新来的’, 100, 200)
    // console.log('插入以后 : ', arr)
    // console.log('返回值 : ', res)

    // 4. shift()
    // var res = arr.shift()
    // console.log('删除之后 : ', arr)
    // console.log('返回值 : ', res)

  4. var arr = [10, 20, 30, 40, 50, 60]
    // // 直接修改 length 去掉的是后面的
    // // 只能从第 2 个开始, 依次向前覆盖
    // // 最后得到的结果是最后一个重复的
    // // 此时在去掉最后一个
    // for (var i = 0; i < arr.length - 1; i++) {
    // // 当前这个被赋值为后一个数据内容
    // arr[i] = arr[i + 1]
    // }
    // arr.length–

    // console.log(arr)

  5. 数组常用方法

     5. reverse()
       => 语法: 数组.reverse()
       => 作用: 反转数组
       => 返回值: 反转以后的数组
    
     6. sort()
       => 语法:
         -> 数组.sort()
           + 一位一位看待按照 ascii 码表的顺序进行排列
         -> 数组.sort(function (a, b) { return a - b })
           + 按照数字从小到大排列
         -> 数组.sort(function (a, b) { return b - a })
           + 按照数字从大到小排列
       => 作用: 数组排序
       => 返回值: 排序好的数组
    
     7. splice()
       => 语法:
         -> 数组.splice(开始索引, 多少个)
         -> 数组.splice(开始索引, 多少个, 数据1, 数据2, 数据3, ...)
           + 按照顺序把要插入的内容插入到数组截取位置
           + 注意: 从哪截取, 从哪插入
       => 作用: 从原始数组内截取部分数据, 并插入新数据(可以选择性插入)
       => 返回值: 必然是一个新的数组
         -> 新数组内按照顺序存储的你截取下来的内容
         -> 如果你没有截取, 那么就是一个空的数组
    

    */

    var arr = [ 1, 6, 4, 2, 9, 5, 7, 3, 8, 11, 22, 17, 10, 35, 21, 100 ]
    console.log('原始数组 : ', arr)

    // 5. reverse()
    // var res = arr.reverse()
    // console.log('反转之后 : ', arr)
    // console.log('返回值 : ', res)
    // 复杂数据类型之间的比较, 是比较地址

    // 6. sort
    // 语法1:
    // var res = arr.sort()
    // console.log('排序之后 : ', arr)
    // 语法2:
    // var res = arr.sort(function (a, b) { return a - b })
    // console.log('排序之后 : ', arr)
    语法3:
    // var res = arr.sort(function (a, b) { return b - a })
    // console.log('排序之后 : ', arr)
    // console.log('返回值: ', res)

    // 7. splice()
    var arr = [ 100, 200, 300, 400, 500, 600 ]
    // 0 1 2 3 4 5
    console.log('原始数组 : ', arr)
    // 语法1:
    // 从 [2] 开始截取 3 个 数据
    // var res = arr.splice(2, 3)
    // console.log('截取之后 : ', arr)
    // console.log('返回值 : ', res)

    // 语法2:
    // 从 [2] 开始截取 1 个数据, 把 ‘新来的’ 插入到 [2] 位置
    // var res = arr.splice(2, 1, ‘新来的’)

    // 从 [2] 开始截取 0 个数据, 把 ‘新来的’ 插入到 [2] 位置, 从原先的 [2] 位置数据向后顺延
    // var res = arr.splice(2, 0, ‘新来的’)

    // 从 [2] 开始截取 1 个数据, 把 '‘新来的’, ‘又一个’, ‘还一个’ 按照顺序插入到 [2] [3] [4] 的位置, 其余的向后顺延
    var res = arr.splice(2, 1, ‘新来的’, ‘又一个’, ‘还一个’)
    console.log('截取之后 : ', arr)
    console.log('返回值 : ', res)

数组塌陷

  1. /*
    数组塌陷
    + 当你删除数组前面的数据的时候
    + 从你删除位置的数据开始, 后面的所有数据, 索引会先前递减
    + 我们管这个行为叫做 数组塌陷
    */

    // 需求: 数组 4 个数据, 遍历每次删除当前这个, 一次一个, 删除完毕数组
    var arr = [ 1, 1, 1, 1, 2, 2, 2, 3, 3, 3, 3, 4 ]
    console.log('原始数组 : ', arr)

    // 出现塌陷问题
    // for (var i = 0; i < arr.length; i++) {
    // // i 就是当前这个数据的索引
    // // aplice(开始索引, 多少个)
    // arr.splice(i, 1)
    // }

    /*
    分析问题

     开始循环
       1. i === 0, len === 4, 条件为 true
          arr.splice(0, 1)
          删除之后 [ 2, 3, 4 ]
          i++
       2. i === 1, len === 3, 条件为 true
         arr.splice(1, 1)
         删除之后 [ 2, 4 ]
         i++
       3. i === 2, len === 2, 条件为 false
         结束循环
    
     解决问题的方向
       1. 不要塌陷: 从后面删除, 倒着循环数组
       2. 让循环控制变量退一步: i--
    

    */

    // 解决塌陷方案1
    // 倒着循环数组
    // for (var i = arr.length - 1; i >= 0; i–) {
    // // i 依旧是数组内每一个的索引, 只不过是倒着的
    // arr.splice(i, 1)
    // }

    /*
    分析问题

     1. i === 3; i >= 0; 条件为 true
        arr.splice(3, 1)
        删除之后, [1, 2, 3]
        i--
     2. i === 2; i >= 0; 条件为 true
        arr.splice(2, 1)
        删除之后, [ 1, 2 ]
        i--
     3. i === 1; i >= 0; 条件为 true
        arr.splice(1, 1)
        删除之后, [ 1 ]
        i--
     4. i === 0; i >= 0; 条件为 true
        arr.splice(0, 1)
        删除之后, []
        i--
     5. i === -1; i >= 0; 条件为 false
        循环结束
    

    */

    // 解决塌陷方案2:
    // i–
    // 只要你执行了 splice, 就执行一个 i–
    for (var i = 0; i < arr.length; i++) {
    if (arr[i] % 2) {
    arr.splice(i, 1)
    i–
    }
    }

    /*
    分析问题

     1. i === 0; i < 4; 条件为 true
        arr.splice(0, 1)
        删除之后 [ 2, 3, 4 ]
        i--
        i++
     2. i === 0; i < 3; 条件为 true
        arr.splice(0, 1)
        删除之后 [ 3, 4 ]
        i--
        i++
     3. i === 0; i < 2; 条件为 true
        arr.splice(0, 1)
        删除之后 [ 4 ]
        i--
        i++
     4. i === 0; i < 1; 条件为 true
        arr.splice(0, 1)
        删除之后 []
        i--
        i++
     5. i === 0; i < 0; 条件为 false
        结束循环
    

    */

    console.log('删除之后 : ', arr)

数组去重

  1. /*
    数组去重 : 去除数组内重复项
    */

    // 原始数组
    // var arr = [ 1, 2, 3, 4, 3, 2, 1, 3, 4, 2, 1, 5, 6, 4, 3, 2, 5 ]
    // console.log('原始数组 : ', arr)
    
    
    
    // 方案1:
    // 拿到第一个和后面进行比较, 如果有一样的就删除一个
    // for (var i = 0; i < arr.length; i++) {
    //   // arr[i] 就是数组内的每一个数据
    //   // arr[0] === 1
    //   // 从 [1] 开始向后查找, 只要后面还有 1 这个数据, 那么把后面的删除了
    //   //  不确定后面还有几个 1, 只要有一个就要删除一个
    //   //  当后面还有 1 的时候, 就删除一个, 否则继续循环 i++
    //   var n = i + 1
    //   while (n < arr.length) {
    //     if (arr[i] === arr[n]) {
    //       arr.splice(n, 1)
    //       i--
    //     }
    //     n++
    //   }
    // }
    
    // 方案2:
    // includes()
    // 语法: 数组.includes(数据)
    // 作用: 判断数组内是否有该数据
    // 返回值: 布尔值
    //   true, 说明有
    //   false, 说明没有
    
    // 准备一个空数组
    // 把原始数组进行遍历, 依次插入到新数组内
    // 在插入之前进行一个判断, 新数组内有这个数据, 就不插入, 没有才插入
    // var newarr = []
    // for (var i = 0; i < arr.length; i++) {
    //   // arr[i] 是数组内的每一个数据
    //   // 如果从 arr[1] 开始后面还有 1 这个数据, 那么删除一个
    //   if (!newarr.includes( arr[i] )) {
    //     newarr.push(arr[i])
    //   }
    // }
    
    // console.log('去重之后 : ', newarr)
    
    
    // 方案3:
    // 计数排序前半部分 + 遍历新数组, 每个索引插入一个
    // var arr = [ 1, 2, 3, 4, 3, 2, 1, 3, 4, 2, 1, 5, 6, 4, 3, 2, 5, 9 ]
    // console.log('原始数组 : ', arr)
    
    // var newarr = []
    // for (var i = 0; i < arr.length; i++) newarr[ arr[i] ] = arr[i]
    // // 把 newarr 中为 undefined 的干掉
    // for (var i = 0; i < newarr.length; i++) {
    //   if (!newarr[i]) {
    //     newarr.splice(i, 1)
    //     i--
    //   }
    // }
    // console.log(newarr)
    
    // 方案4:
    // 使用 sort 排序
    // 判断紧挨着的两个是否一样, 如果一样, 删除一个
    // var arr = [ 1, 2, 3, 4, 10, 3, 2, 11, 1, 3, 4, 2, 11, 1, 10, 5, 6, 4, 3, 2, 5, 9 ]
    // console.log('原始数组 : ', arr)
    
    // arr.sort()
    // console.log('排序之后 : ', arr)
    // // 遍历
    // for (var i = 0; i < arr.length; i++) {
    //   // 判断当前和下一个一样
    //   if (arr[i] === arr[i + 1]) {
    //     arr.splice(i, 1)
    //     i--
    //   }
    // }
    // console.log('去重之后 : ', arr)
    
    
    // 方案5: 和方案3一致, 使用对象
    // var arr = [ 1, 2, 3, 4, 10, 3, 2, 11, 1, 3, 4, 2, 11, 1, 10, 5, 6, 4, 3, 2, 5, 9 ]
    // console.log('原始数组 : ', arr)
    
    // 准备一个新的对象
    // var obj = {}
    // for (var i = 0; i < arr.length; i++) obj[ arr[i] ] = '随便'
    // // 把对象内的每一个索引当做 数据 插入到数组内
    // var newarr = []
    // for (var k in obj) {
    //   newarr.push(k - 0)
    // }
    // console.log(newarr)
    
    // 6. Set()
    // Set 是一个 js 内的数据结构, 长得和数组差不多
    // 特点: 不接受重复数据
    // 语法:
    //   创建空 Set: var s = new Set()
    // var s = new Set()
    // console.log(s)
    //   创建带有数据的 Set: var s = new Set([ 数据1, 数据2, 数据3 ])
    // var s = new Set([ 1, 2, 3, 1, 2, 3 ])
    // console.log(s)
    
    var arr = [ 1, 2, 3, 4, 10, 3, 2, 11, 1, 3, 4, 2, 11, 1, 10, 5, 6, 4, 3, 2, 5, 9 ]
    console.log('原始数组 : ', arr)
    
    // 利用 Set 数据结构
    // var s = new Set(arr)
    // console.log(s)
    
    // // 把 Set 数据结构转换会数组数据类型
    // // 方法1: Array.from()
    // var res1 = Array.from(s)
    // console.log(res1)
    // // 方案2: 展开运算符(...)
    // var res2 = [ ...s ]
    // console.log(res2)
    
    var r1 = Array.from( new Set(arr) )
    console.log(r1)
    var r2 = [ ...new Set(arr) ]
    console.log(r2)
    

函数回调

  1. /*
    回调函数 callback
    + 概念: 把 函数A 当做实参传递到 函数B 内
    在 函数B 内以形参的方式调用 函数A
    此时, 我们就说 函数A 是 函数B 的回调函数
    + 作用:
    1. 封装和遍历相关的内容
    2. 封装和异步相关的内容

     思考:
       + 封装: 为了把一个内容(行为) 放在一个函数内, 为了复用(灵活的复用)
       + 遍历: 使用循环从头到尾的获取到数组内的每一个数据
         => 我随着循环, 每次都做一样的事情, 但是可能有细节不一样
     例子:
       + 你作为我封装的一个对象
       + 功能: 跑腿
    

    */

    // function a(cb) {
    // // 这里的 cb 形参接受的就是全局函数 b 的存储地址
    // // 此时这里的形参 cb 和全局变量 b 操作的是一个函数地址
    // // cb() // 等价于在调用 全局b 函数

    // for (var i = 0; i < 10; i++) {
    // cb()
    // }
    // }

    // function b() {
    // console.log(‘我是全局 b 函数’)
    // // 在这里做出你每次想做的事情就可以了
    // }

    // // 把 b 函数当做参数传递到 a 函数内了
    // // 变量 b 保存的是 一个函数的地址
    // // 这里当做实参传递进去的也就是一个函数的地址
    // a(b)

    function sort(cb) {
    var arr = [ 10, 20, 30, 40, 50 ]
    for (var i = 0; i < arr.length - 1; i++) {
    // 此时的 cb 就是在调用 b 函数
    // cb() 函数调用阶段, 书写的叫做实参
    var res = cb(arr[i], arr[i + 1])
    if (res >= 0) {
    var tmp = arr[i]
    arr[i] = arr[i + 1]
    arr[i + 1] = tmp
    }
    }
    }
    // // 这个 b 函数的调用, 就是写在 sort 函数内 cb(arr[i], arr[i + 1])
    // // 所以这里 return 出去的内容, 就应该再 cb 前面接受返回值
    // sort(function b(param1, param2) { return param2 - param1 })

数组常用办法forEach

  1. /*
    数组常用方法3
    + forEach()
    + 专门用来遍历数组的方法

      语法:
        => 数组.forEach(function (item, index, arr) {
          item 表示数组的每一项
          index 表示数组每一项的索引
          arr 表示原始数组
        })
      返回值:
        => 没有, undefined
      意义: 用来遍历数组
    */
    
    // var arr = [ 100, 200, 300, 400, 500, 600 ]
    // var arr2 = [ 10, 20, 30, 40 ]
    
    // a 会根据数组内有多少数据, 执行多少回
    // arr.forEach(function a(item, index, arr) {
    //   console.log('我执行了', item, index, arr)
    //   // 可以直接书写每一次循环你要做的事情
    // })
    
    
    
    // 我自己模仿一个 forEach 方法
    // function myForEach(cb) {
    //   // 需要在这里直到是谁调用了我
    //   // 我就去遍历谁
    //   // console.log('我被谁调用了呢 ? ', this)
    
    //   // 只需要遍历 this
    //   for (var i = 0; i < this.length; i++) {
    //     // 在循环内, this[i] 是当前这个数组的每一项
    //     // 在循环内, i 是当前这个数组每一项的索引
    //     // 在循环内, this 就是当前这个数组
    //     cb(this[i], i, this)
    //   }
    // }
    
    // 1. 能不能像 forEach 一样直接被 数组.myForEach 调用
    // 需要让我封装的方法能被数组直接调用
    // 需要把这个方法赋值给一个 "空间" 内
    // 把我们自己写的 myForEach 放在 "数组方法空间" 内
    // "数组方法空间" 是一个对象数据类型
    // "数组方法空间" 被我们叫做 Array.prototype
    // Array.prototype.myForEach = myForEach
    // var arr = [ 10, 20 ]
    // arr.myForEach()
    
    // arr.myForEach(function (item, index, arr) { console.log('我是 arr 调用', item, index, arr) })
    // arr2.myForEach()
    
    // 求 arr 数组内每一项的和
    // 在循环内做的事情: 把每一项叠加在一个初始变量身上
    // var sum = 0
    // arr.myForEach(function (item) {
    //   sum += item
    // })
    // console.log(sum)
    
    
    // 2. forEach 是用来遍历数组的
    // 在 myForEach 内也需要可以遍历数组
    // 遍历的不是我随便定义的数组, 而是哪一个数组调用我, 我遍历谁
    // a1.forEach()   在 forEach 内遍历 a1 数组
    // a2.forEach()   在 forEach 内遍历 a2 数组
    // a2.myForEach()   在 myForEach 内遍历 a2 数组
    // 在我封装的方法内直到, 是哪一个数组在调用我
    // 在函数内有一个关键字, 叫做 this
    //   今天: 哪一个数组调用这个方法, 方法内的 this 就是谁
    
    
    // 例子: 现在有一个对象叫做 obj
    var obj = {}
    var name = 'Jack'
    console.log(obj)
    // 需要把 myForEach 放在 obj 内
    obj.myForEach = myForEach
    // 需要把一个 name 放在对象内
    obj.name = name
    console.log(obj)
    
    
    
    
    
    
    // 1. 需要封装一个方法, 让数组可以直接调用
    var arr = [ 100, 200, 300, 400 ]
    // 需要把这个方法放在 Array.prototype 这个对象内
    Array.prototype.myForEach = myForEach
    function myForEach(cb) {
      // 2. 在我们封装好的函数内, this 就是调用我的那个数组
      // 遍历 this
      for (var i = 0; i < this.length; i++) {
        // 循环遍历多少遍, 就把锦囊执行多少遍
        // 在调用锦囊的时候, 把 数组的每一项 索引 原始数组 给到锦囊内部
        cb(this[i], i, this)
      }
    }
    
    arr.myForEach(function (item, index, arr) {
      console.log('锦囊妙计', item, index, arr)
    })
    

数组常用办法map

  1. /*
    封装一个方法 - abc
    + 需求:
    => 根据原始数组的长度 返回 给我一个新的数组
    => 在回调函数内可以对原始数组内每一个数据进行操作(我需要的操作)
    => 新数组内得到数据, 就是操作以后的数据

      数组常用方法 - map
        + 语法: 数组.map(function (item, index, arr) {})
        + 作用: 对原始数组进行映射
        + 返回值: 就是一个和原始数组一样长度的新数组, 并且内部的数据是被映射操作过的内容
    */
    
    var arr = [ 10, 20, 30, 40 ]
    
    var res = arr.map(function (item) { return item * 10 })
    console.log(arr)
    console.log(res)
    
    
    
    
    
    
    
    // 1. 准备方法
    // Array.prototype.abc = abc
    // function abc(cb) {
    //   // 根据需求1
    //   //   必须要建立一个新数组了
    //   var ary = []
    
    //   // 我们需要根据原始数组(this) 的长度和 cb 的操作
    //   // 向 ary 内添加数据
    //   for (var i = 0; i < this.length; i++) {
    //     // 使用 abc 方法的人, 会把他想要的操作条件写在 aaa 内
    //     // 需要调用 cb, 并且把每一项给到 aaa 函数
    //     // r 接受到的及时 aaa 函数内的返回值
    //     // 因为 aaa 内返回的是 每一项的 * 10 的结果
    //     // r 得到的就是每一项 * 10 的结果
    //     var r = cb(this[i], i, this)
    //     ary.push(r)
    //   }
    
    
    //   // 把操作好的数据返回
    //   return ary
    // }
    
    // // 2. 将来使用的时候
    // var arr = [ 10, 20, 30, 40, 60, 80 ]
    // console.log('原始数组 : ', arr)
    
    // var res = arr.abc(function aaa(item, index, arr) {
    //   // 一些操作, 假设我的操作是 * 10
    //   // 以返回值的形式把结果给出去
    //   return item * 10 + 345
    // })
    
    // console.log(res)
    
    // res === [ 100, 200, 300, 400 ]
    

数组常用办法filter

  1. /*
    封装方法
    + 需求: 根据我的条件对原始数组进行过滤, 把原始数组中满足我条件的所有项拿出来
    组成一个新的数组返回
    + 例子:
    => 原始数组 [ 10, 20, 30, 40 ]
    => 条件 > 20
    => 结果 [ 30, 40 ]

     filter
       + 语法: 数组.filter(function (item, index, arr) {})
       + 返回值: 一个新的数组
         => 原始数组中满足条件的项
         => 在回调函数中以 return 的形式书写 过滤条件
    

    */

    // 1. 准备方法
    // Array.prototype.myFilter = function (cb) {
    // // 1-1. 准备一个新的数组
    // var ary = []

    // // 1-2. 根据 回调函数 的条件, 向 新数组内 添加成员
    // for (var i = 0; i < this.length; i++) {
    // // 需要调用 cb
    // var r = cb(this[i], i, this)

    // // ary.push(this内满足条件的项)
    // r && ary.push(this[i])
    // }

    // // 1-3. 返回新数组
    // return ary
    // }

    // // 2. 将来使用的时候
    // var arr = [ 10, 20, 30, 40 ]
    // var res = arr.filter(function (item, index, arr) {
    // // 过滤条件
    // return item > 20
    // })

    // console.log('原始数组 : ', arr)
    // console.log('过滤以后 : ', res)

数组常用办法every和some

  1. /*
    数组常用方法 - every 和 some

    every
      + 判断数组内是不是所有项都满足条件
      + 如果所有项都满足条件, 那么返回值是 true
      + 只要有任意一项不满足条件, 那么返回值是 false
    
    some
      + 判断数组内是不是有某一项满足条件
      + 只要数组内任意一项满足条件, 那么返回值就是 true
      + 只有所有项都不满足条件的时候, 返回值才是 false
    

    */

    // // 1. 准备方法
    // Array.prototype.myEvery = function (cb) {
    // // 1-1. 提前假设一个变量, 假设所有都满足条件
    // var flag = true

    // // 1-2. 循环遍历数组来验证我的假设
    // for (var i = 0; i < this.length; i++) {
    // var r = cb(this[i], i, this)

    // // 如果在循环过程中, r 为 false 了, 说明当前这一个不是满足条件的项
    // // 推翻我的假设
    // if (!r) {
    // flag = false
    // break
    // }
    //
    // }

    // // 1-3. 返回我的 flag
    // return flag
    // }

    // // 2. 将来使用的时候
    // var arr = [ 10, 20, 30, 40, 50 ]
    // var res = arr.myEvery(function (item, index, arr) {
    // console.log(item)
    // return item > 10
    // })
    // console.log(res)

    // 1. 准备方法
    Array.prototype.mySome = function (cb) {
    // 1-1. 提前假设一个变量, 假设完全没有
    var flag = false

    // 1-2. 循环遍历数组来验证我的假设
    for (var i = 0; i < this.length; i++) {
      var r = cb(this[i], i, this)
    
      if (r) {
        flag = true
        break
      }
    }
    
    // 1-3. 返回我的 flag
    return flag
    

    }

    // 2. 将来使用的时候
    var arr = [ 10, 20, 30, 40, 50 ]
    var res = arr.some(function (item, index, arr) {
    console.log(item)
    return item > 10
    })
    console.log(res)

数组常用办法三

  1. /*
    数组常用方法3
    1. flat()
    => 语法: 数组.flat(数字)
    -> 如果不传递参数, 默认拍平一层
    -> 传递的数字是几, 就拍平多少层
    -> 不管多少维度都直接拍平, Infinity
    => 作用: 拍平一个数组(把多维转换成一维)

        2. find()
          => 语法: 数组.find(function (item, index, arr) {})
          => 返回值: 数组中满足条件的第一个
            -> 以 return 的形式书写条件
    
        3. findIndex()
          => 语法: 数组.findIndex(function (item, index, arr) {})
          => 返回值: 数组中满足条件的第一个的索引位置
            -> 以 return 的形式书写条件
    
        4. includes()
          => 语法: 数组.includes(数据)
          => 返回值: 一个布尔值
            -> 如果数组内有改数据, 那么就是 true
            -> 如果数组内没有该数据, 那么就是 false
    
        5. fill()
          => 语法: 数组.fill(要填充的数据, 开始索引, 结束索引)
            -> 开始索引不写默认是 0
            -> 结束索引不写, 默认是最后一位的索引
            -> 特点: 索引 包前不包后(包含开始索引, 不包含结束索引)
          => 作用: 替换, 按照索引位置替换数组内指定索引的数据
            -> 等价于 arr[2] = '你好 世界'
          => 注意: 直接改变原始数组
          => 注意: 只能替换现有数据, 不能新增
    
        6. reduce()
          => 语法: 数组.reduce(function (prev, item, index, arr) {}, init)
            -> init 如果不写, 默认使用数组中的第一个数据
          => 作用: 叠加
          => 返回值: 就是叠加后的结果
    */
    
    // 1. flat
    // var arr = [10, [20, 30, [40, 50, [60, 70, [80, [90]]]]]]
    // var res = arr.flat(Infinity)
    // console.log(arr)
    // console.log(res)
    
    // 2. find()
    // var arr = [ 10, 20, 30, 40, 50, 60 ]
    // var res = arr.find(function (item) {
    //   return item % 3 === 0
    // })
    // console.log(res)
    
    // 3. findIndex()
    // var arr = [ 10, 20, 30, 40, 50, 60 ]
    // var res = arr.findIndex(function (item) {
    //   return item % 3 === 0
    // })
    // console.log(res)
    
    // 4. includes()
    // var arr = [ 10, 20, 30, 40, 50, 60 ]
    // var res = arr.includes(33)
    // console.log(res)
    
    // 5. fill()
    // var arr = [ 10, 20, 30, 40, 50, 60 ]
    // console.log('原始数组 : ', arr)
    // arr.fill('新来的')
    // 从 [2] 开始到 [5] 结束, 包含 [2] 不包含 [5]
    // arr.fill('新来的', 2, 5)
    // arr.fill('新来的', 2)
    // arr.fill('新来的', 2, 100)
    // console.log('原始数组 : ', arr)
    
    // 6. reduce()
    var arr = [ 10, 20, 30, 40, 50, 60 ]
    var res = arr.reduce(function (prev, item) {
      console.log(prev, item)
      return prev + item
    }, 100)
    console.log('最终结果: ', res)
    
    /*
      你设置了 init 位置参数
        循环第一次, prev 就是 init 位置的值, item 就是数组内的第一项
        循环第二次, prev 就是上一次 return 的内容, item 是数组当前第二项
    
      你没有设置 init 位置参数
        此时, 会默认使用数组中的 [0] 这一项当做 init 位置参数
        循环第一次, prev 就是数组 [0] 的值, item 就是索引当前项 [1]
        如果没有 init 位置的数据, 那么数组从 [1] 开始遍历
    */
    

数组常用办法四

  1. 数组常用方法4

     1. concat()
       + 拼接数组
       + 语法: 数组.concat(数组2, 数据, 数组3)
       + 作用: 把所有参数内的数组或者数据追加到原始数组的最后面, 如果参数是数组, 那么拆开追加
       + 返回值: 拼接好的数组
       + 注意: 不会改变原始数组
    
     2. join()
       + 连接数组
       + 语法: 数组.join(连接符号)
         => 连接符号如果不写, 默认使用 ','
       + 作用: 把数组内每一项使用连接符号连接为一个字符串
       + 返回值: 是一个字符串类型
       + 注意: 不会改变原始数组
    
     3. slice()
       + 截取数组
       + 语法: 数组.slice(开始索引, 结束索引)
         => 特点: 包前不包后
         => 特点2: 可以写负整数, 就是倒数第几个. 等价于 length + 负整数
         => 开始索引不填写, 默认是 0
         => 结束索引不填写, 默认是 length
       + 返回值: 一个新的数组
         => 里面存放的就是你截取出来的内容
       + 注意: 不会改变原始数组
    
     4. indexOf()
       + 语法:
         => 数组.indexOf(要查找的数据)
         => 数组.indexOf(要查找的数据, 开始索引)
       + 返回值:
         => 从前向后检索, 检索第一个满足要求的数据
         => 返回第一个满足要求的数据的索引位置
         => 如果有这个数据, 返回索引位置
         => 如果没有这个数据, 返回 -1
    
     5. lastIndexOf()
       + 语法:
         => 数组.lastIndexOf(要查找的数据)
         => 数组.lastIndexOf(要查找的数据, 开始索引)
       + 返回值:
         => 从后向前检索, 检索第一个满足要求的数据
         => 返回第一个满足要求的数据的索引位置
         => 如果有这个数据, 返回索引位置
         => 如果没有这个数据, 返回 -1
    

    */

    // 1. concat()
    // var arr = [ 10, 20, 30 ]
    // console.log(arr)
    // var a2 = [ 40, 50, 60 ]
    // var a3 = [ 70, 80, 90 ]
    // var res = arr.concat(a2, a3)
    // console.log(arr)
    // console.log(res)

    // 2. join()
    // var arr = [ 2022, 2, 28 ]
    // console.log(arr)
    // var res = arr.join(’_’)
    // console.log(arr)
    // console.log(res)
    // console.log(typeof res)

    // 3. slice()
    // var arr = [ 10, 20, 30, 40, 50, 60, [70] ]
    // // 0 1 2 3 4 5
    // console.log('原始数组 : ', arr)
    // // 从 [2] 截取到 [5], 包含 [2] 不包含 [5]
    // // var res = arr.slice(2, 5)
    // // 从 [1] 截取到 [-1], 这里的 [-1] 等价于 arr.length + -1
    // // var res = arr.slice(1, -1)
    // var res = arr.slice()
    // console.log(arr)
    // console.log('返回值 : ', res)

    // arr[2] = ‘修改一下’
    // console.log(arr)
    // console.log(res)

    // 4. indexOf()
    // var arr = [ 10, 20, 30, 20, 10, 20, 30 ]
    // console.log('原始数组 : ', arr)
    // // var res = arr.indexOf(20)
    // // 从 [2] 位置开始向后检索
    // var res = arr.indexOf(20, 2)
    // console.log(res)

    // 5. lastIndexOf()
    // var arr = [ 10, 20, 30, 20, 10, 20, 30 ]
    // console.log(arr)
    // var res = arr.lastIndexOf(20)
    // 从 [4] 位置开始向前查找
    // var res = arr.lastIndexOf(20, 4)
    // console.log(res)

数组常用办法总结

  1. /*
    数组常用方法 - 总结

     1. push()
       => 后面追加
       => 返回值: 追加后数组最新的长度
    
     2. pop()
       => 后面删除
       => 返回值: 被删除的数据
    
     3. unshift()
       => 前面添加
       => 返回值: 添加后数组最新的长度
    
     4. shift()
       => 前面删除
       => 返回值: 被删除的数据
    
     5. reverse()
       => 数组反转
       => 返回值: 反转后的数组
    
     6. sort()
       => 数组.sort() ASCII
       => 数组.sort(function (a, b) { return a - b }) 升序
       => 数组.sort(function (a, b) { return b - a }) 降序
       => 数组排序
       => 返回值: 排序后的数组
    
     7. splice()
       => 数组.splice(开始索引, 多少个)
       => 数组.splice(开始索引, 多少个, 插入数据)
       => 数组截取并选择性的插入数据, 注意: 从哪里删除, 从哪里插入
       => 返回值: 一个新的数组, 存储的是截取出来的所有内容
    
     ===================== 以上数组常用方法, 都是直接改变原始数组 =====================
    
     8. concat()
       => 拼接数组
       => 返回值: 拼接好的新数组
    
     9. join(连接符)
       => 使用连接符连接数组内的每一项
       => 返回值: 一个字符串类型, 使用连接符连接好的内容
    
     10. slice()
       => 数组.slice(开始索引, 结束索引)
         -> 特点1: 包前不包后
         -> 特点2: 可以填写负整数
       => 截取数组内的内容
       => 返回值: 一个新的数组, 数组内存储的是截取出来的内容
    
     11. indexOf()
       => 从前向后检索数据出现的索引位置
       => 返回值: 如果有这个数据, 就是第一次出现的索引位置, 如果没有这个数据, 就是 -1
    
     12. lastIndexOf()
       => 从后向前检索数据出现的索引位置
       => 返回值: 如果有这个数据, 就是第一次出现的索引位置, 如果没有这个数据, 就是 -1
    
     13. forEach(function (item, index, arr) {})
       => 遍历数组
       => 返回值: 没有
    
     14. map(function (item, index, arr) {})
       => 映射数组
       => 返回值: 一个新的数组, 对原始数组内每一项操作后的结果
    
     15. filter(function (item, index, arr) {})
       => 过滤数组
       => 返回值: 一个新的数组, 原始数组内满足条件的新数组
    
     16. every(function (item, index, arr) {})
       => 判断是否每一项都满足条件
       => 返回值:
         -> 如果数组内每一项都满足条件, 那么返回 true
         -> 只要有任何一项不满足条件, 那么返回 false
    
     17. some(function (item, index, arr) {})
       => 判断是否某一项满足条件
       => 返回值:
         -> 如果数组内有任何一项满足条件, 那么返回 true
         -> 只有数组内所有都不满足条件, 那么返回 false
    
     18. find(function (item, index, arr) {})
       => 根据条件查找数组中的数据
       => 返回值: 查找到的数据
    
     19. findIndex(function (item, index, arr) {})
       => 根据条件查找数组中的数据所在的索引位置
       => 返回值: 查找到的数据的索引位置
    
     20. flat(数字)
       => 拍平数组
       => 数组: 书写多少, 就是拍平多少层
         -> 可以书写 Infinity 来表示全部拍平
       => 返回值: 一个被拍平的数组
    
     21. fill()
       => 填充数组
       => 数组.fill(填充数据, 开始索引, 结束索引)
         -> 特点: 包前不包后
       => 注意: 会直接改变原始数组
       => 注意: 只能填充现有索引位置数据, 不能新增数据
    
     22. includes()
       => 判断是否存在数据
       => 返回值: 一个布尔值
         -> 如果数组内有该数据, 那么返回 true
         -> 如果数组内没有该数据, 那么返回 false
    
     23. reduce(function (prev, item, index, arr), init)
       => init 可以写可以不写, 不写的时候默认使用数组 [0] 位置的数据
       => 当 init 不写的时候, 遍历会从 [1] 开始
       => 当 init 书写的时候, 遍历会从 [0] 开始
       => 叠加数组
       => 返回值: 最终的叠加结果
    

    */

数组去重

  1. /*

​ 数组去重 - if
*/

var arr = [ 10, 20, 30, 40, 10, 20, 30, 10, 20, 30, 10 ]
console.log('原始数组 : ', arr)

// 1. 遍历数组
for (var i = 0; i < arr.length; i++) {
  // i 表示当前这一项的索引
  // 从 i + 1 开始查找, 找找看后面还有没有这个数据
  var r = arr.indexOf( arr[i], i + 1 )
  // 没有学习 indexOf 之前, 在这里书写一个 循环, 找到 索引位置

  // 判断是否存在
  if (r !== -1) {
    arr.splice(r, 1)
    i--
  }
}

console.log('去重之后 : ', arr)

作业

  1. /*
    按照顺序向数组内插入一个数据
    */

    // 已知排序完整的数组
    var arr = [ 10, 20, 30, 40, 50 ]

    // 准备要插入的数字
    var n = 22

    // code run here …

    // 结果: 把 n 按照现有顺序插入到数组内

    /*
    预习:
    => 快速排序
    => 插入排序
    */

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值