_5(4)案例

day _5(4) 案例

案例1 数组去重
  */

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

    // 1. 排序, 遍历
    // arr.sort()
    // console.log('排序之后 : ', arr)
    // // 遍历数组, 只要前一个和后一个一样, 删除一个
    // for (var i = 0; i < arr.length; i++) {
    //   // 当前这个 arr[i]
    //   // 下一个 arr[i + 1]
    //   if (arr[i] === arr[i + 1]) {
    //     arr.splice(i, 1)
    //     i--
    //   }
    // }
    // console.log('去重之后 : ', arr)


    // 2. 第二个循环查找后面有没有长得一样的
    // 分析: 第二个循环的目的, 为了找到后续内容中是否有重复的(indexOf)
    // for (var i = 0; i < arr.length; i++) {
    //   // i 当前这个数据的索引
    //   var repeat = arr.indexOf(arr[i], i + 1)
    //   // repeat 如果为 -1 说明后面没有了
    //   if (repeat === -1) continue
    //   // repeat 如果不为 -1, 那么 repeat 索引位置就是那个重复的数据
    //   arr.splice(repeat, 1)
    //   i--
    // }
    // console.log('去重之后 : ', arr)

    // 3. Set
    // ES2015 推出的一种数据结构, 特点: 不接受重复数据
    // 语法结构创建: new Set([ 数据, 数据, 数据 ])
    // var s = new Set([ 10, 20, 30, 10, 20, 30 ])
    // console.log(s)
    // 3-1. 利用 Set 数据结构把数组内的重复数据摒弃
    // var s = new Set(arr)
    // // console.log(s)
    // // 3-2. 把 s 还原成一个数组
    // // 语法: Array.from()
    // var r1 = Array.from(s)
    // console.log(r1)
    // // 语法: ... 运算符
    // var r2 = [ ...s ]
    // console.log(r2)
    // var r1 = [ ...new Set(arr) ]
    // var r2 = Array.from(new Set(arr))
    // console.log(r1, r2)


    // 4. 计数排序的逻辑
    // var tmp = []
    // for (var i = 0; i < arr.length; i++) {
    //   var item = arr[i]
    //   tmp[item] = '随便'
    // }
    // arr = []
    // for (var i = 0; i < tmp.length; i++) {
    //   if (!tmp[i]) continue
    //   arr.push(i)
    // }
    // console.log(arr)

    // var tmp = {}
    // for (var i = 0; i < arr.length; i++) {
    //   var item = arr[i]
    //   tmp[item] = '随便'
    // }
    // arr = []
    // for (var k in tmp) {
    //   arr.push(k - 0)
    // }
    // console.log(arr)


    // 5. 创建新数组, 依次插入
    // var result = []
    // for (var i = 0; i < arr.length; i++) {
    //   var item = arr[i]
    //   // 判断, 如果 result 内没有 item 这个数据, 才向内插入
    //   if (result.indexOf(item) === -1) result.push(item)
    // }
    // console.log('去重之后 : ', result)
案例2 数组常用方法 forEach
  • 语法: 数组.forEach(function (item, index, origin) {})
    => item 就是数组内的每一项
    => index 就是数组内每一项的索引
    => origin 就是原始数组
  • 返回值: undefined
// 问题: 为什么可以书写 数组.push()
//   私人: JS 的语法内, 设计了一个 "空间", 里面存储了一系列数组方法
//        如果你设计一个方法, 也想 数组.xxx() 的话, 把你设计的方法也放在这个 "空间"
//   空间: Array.prototype

// 添加到 Array.prototype 上的方法, 就是为了给所有的数组使用的
// 当你调用这个方法的时候, 需要用 数组 去调用
// Array.prototype.myPush = function myPush() {
//   // 问题1: 向哪一个数组内追加数据
//   //   你不确定将来调用你的数据变量名是什么
//   //   不能使用一个准确的名字
//   //   可以使用一个关键字叫做 this
//   //   谁调用的 myPush, this 就是谁
//   // console.log(this)
//   //   向 this 这个数组内追加数据

//   // 问题2: 追加什么数据
//   //   arguments 内有多少个数据, 向 this 内追加多少个数据

//   // 循环遍历 arguments, 为了拿到每一个要追加的数据
//   for (var i = 0; i < arguments.length; i++) {
//     var item = arguments[i]
//     // console.log(item)
//     // 把 item 依次追加到 this 里面
//     this[this.length] = item
//   }

//   // 返回值: 追加后最新的长度
//   return this.length
// }



// 需求: 自己封装一个 myPush 方法
// 要求: 和 push 方法的 调用方式 / 传递参数 / 返回值 一模一样

// 为了调用方式一样, 我需要把我自己封装的方法放在 Array.prototype 上
// Array.prototype.myPush = function () {
//   // 在该函数内, this 关键字表示的就是调用 myPush 方法的数组
//   // 在该函数内, arguments 表示的是你传递的所有实参的集合
//   // 目的: 把 arguments 内的每一个追加到 this 内
//   for (var i = 0; i < arguments.length; i++) {
//     this[this.length] = arguments[i]
//   }

//   // 为了返回值一样
//   return this.length
// }

// 我想用这个 myPush 怎么办
// var arr = [ 100, 200, 300 ]
// var res = arr.myPush('新来的', '新来的2')
// console.log('追加之后 : ', arr)
// console.log('返回值 : ', res)



// 需求: 自己封装一个 muUnshift 方法
// 要求: 和数组的 unshift 方法 调用方式 / 传递参数 / 返回值 一模一样

// 把 myUnshift 方法添加到 Array.prototype 上
// Array.prototype.myUnshift = function () {
//   // 把 arguments 内的内容给到 this 的最前面
//   // 关注原始数组的 length
//   var len = this.length
//   // 关注要插入多少个数据
//   var insertLen = arguments.length

//   // 从 this 的最后一个数据开始, 每一个数据向后顺延 insertLen 个索引位置
//   // 倒着循环 this, 拿到每一个需要移动的数据
//   for (var i = len - 1; i >= 0; i--) {
//     this[i + insertLen] = this[i]
//   }

//   // 把 arguments 内的内容一次添加到 this 内
//   // arguments 的索引 就是 this 内数据的索引位置
//   for (var i = 0; i < insertLen; i++) {
//     this[i] = arguments[i]
//   }

//   // 制作一个返回值
//   return this.length
// }

// var arr = [ 10, 20, 30 ]
// var res = arr.myUnshift('新来的1', '新来的2')
// console.log('插入之后 : ', arr)
// console.log('返回值 : ', res)



// 需求: 封装 myShift 方法
// Array.prototype.myShift = function () {
//   // 判断
//   if (this.length <= 0) return ''

//   // 拿出 this 的 [0] 位置数据
//   var data = this[0]

//   // 把从 [1] 开始所有的数据直接向前移动
//   for (var i = 1; i < this.length; i++) {
//     this[i - 1] = this[i]
//   }

//   this.length--

//   // 制作返回值
//   return data
// }

// var arr = [ 10, 20, 30 ]
// var res = arr.myShift()
// console.log('插入之后 : ', arr)
// console.log('返回值 : ', res)






// 需求: 封装一个 myForEach 方法, 能帮我自动遍历数组
//   遍历的目的就是为了拿到每一个数据, 想做事
//   把我想做的事情放在一个 函数内, 以回调函数的形式给到 myForEach

// 方法添加到 Array.prototype 上
// Array.prototype.myForEach = function (cb) {
//   // 遍历谁 ? this
//   for (var i = 0; i < this.length; i++) {
//     // 每一个索引 i
//     // 每一个数据 this[i]
//     // console.log(this[i])

//     // 随着循环调用 cb
//     // 当你调用 cb 的时候, 把 数组的每一项 内容回传
//     cb(this[i], i, this)
//   }
// }

// 将来我需要遍历数组的时候
// var arr = [ 100, 200, 300, 400, 500 ]

// 遍历数组: 想做事
// arr.myForEach(function (item, index, origin) {
//   console.log('随着循环做点事情', item, index, origin)
// })

// 求和
// var sum = 0
// arr.myForEach(function (item) {
//   sum += item
// })

// console.log(sum)
案例3 数组方法 map
  • 语法: 数组.map(function (item, index, origin) {})
  • 返回值: 根据条件映射出来的新数组
  • 注意: 映射条件以 rteurn 的形式书写
   // 需求: myMap 方法
    // 要求: 根据原始数组 和 我给出的条件, 把 原始数组内的内容 全部修改, 放在一个新数组内返回

    // Array.prototype.myMap = function (cb) {
    //   // 1. 创建一个新数组
    //   var res = []

    //   // 2. 想办法向新数组内添加成员
    //   // 2-1. 遍历原始数组
    //   for (var i = 0; i < this.length; i++) {
    //     // 2-2. 逐个向 res 内添加数据
    //     // 问题: 添加一个什么数据 ?
    //     // 利用回调函数的返回值, 接受加工结果
    //     //   当 i === 0 的时候, cb(10, 0), 返回值是 100 赋值给了 r
    //     //   当 i === 1 的时候, cb(20, 1), 返回值是 200 赋值给了 r
    //     //   当 i === 2 的时候, cb(30, 2), 返回值是 300 赋值给了 r
    //     var r = cb(this[i], i, this)
    //     // 只要随着循环每一次把 r 追加到 res 数组内
    //     res.push(r)
    //   }

    //   // 3. 把新数组返回
    //   return res
    // }

    // // 将来使用的时候
    // var arr = [ 10, 20, 30 ]
    // var res = arr.myMap(function (item, index, origin) {
    //   // 对每一个数据进行加工
    //   return item * 100
    // })
    // console.log(arr)
    // console.log(res)

    // res === [ 数据, 数据, 数据 ]


    /*
      数组方法 map
        + 语法: 数组.map(function (item, index, origin) {})
        + 返回值: 根据条件映射出来的新数组
        + 注意: 映射条件以 rteurn 的形式书写
    */

    var arr = [ 10, 20, 30 ]
    var res = arr.map(function (item, index, origin) {
      return item * 100
    })
    console.log(arr)
    console.log(res) 
案例4 方法: filter
  • 语法: 数组.filter(function (item, index, origin) {})
  • 作用: 从原始数组中过滤出满足要求的项, 放在新数组内
  • 返回值: 一个新数组, 存储的是原始数组中满足要求的数据
  • 注意: 以 return 的形式书写 过滤条件
// var arr = [ 100, 200, 300, 400, 500, 300, 400, 300 ]
// var res = arr.filter(function (item) {
//   return item > 300
// })
// console.log(res)

// Array.prototype.myFilter = function (cb) {
//   // 1. 准备一个新数组
//   var result = []

//   // 2. 向 result 内添加数据
//   for (var i = 0; i < this.length; i++) {
//     var r = cb(this[i], i, this)
//     // 当 r 为 true 的时候, 表示当前这一项满足条件, 需要插入到 result 内
//     r && result.push(this[i])
//   }

//   // 3. 返回新数组
//   return result
// }

// 使用的时候
// var res = arr.myFilter(function (item) {
//   // 以 return 的形式书写条件
//   return item > 300
// })
// console.log(res)

// 删除源数组内所有的 300
// arr = arr.myFilter(function (item) { return item !== 300 })
// console.log(arr)
案例5 方法: find()
  • 语法: 数组.find(function (item, index, origin) {})
  • 返回值: 原始数组内满足条件的第一项
  • 注意: 以 return 的形式书写查找条件
    // var arr = [
    //   { id: 1, name: 'Jack' },
    //   { id: 2, name: 'Rose' },
    //   { id: 3, name: 'Tom' },
    //   { id: 2, name: 'Jerry' }
    // ]

    // // 我只有一个 id 信息
    // var id = 2

    // // 想从 arr 数组内找到 id 为 2 的数据
    // // var user = arr.find(function (item) {
    // //   // item 是每一项, 每一个 对象 数据类型
    // //   return item.id === id
    // // })
    // // console.log(user)

    // Array.prototype.myFind = function (cb) {
    //   // 1. 准备一个变量接受结果
    //   var res = undefined

    //   // 2. 从数组内找到对应的数据赋值给 res
    //   for (var i = 0; i < this.length; i++) {
    //     var r = cb(this[i], i, this)
    //     if (r) {
    //       // 把 this[i] 赋值给 res
    //       res = this[i]
    //       break
    //     }
    //   }

    //   // 3. 把 res 当做返回值
    //   return res
    // }

    // // 使用的时候
    // var res = arr.myFind(function (item) {
    //   console.log('我执行了')
    //   return item.id === id
    // })
    // console.log(res)


    // var arr = [
    //   { id: 1, name: 'Jack' },
    //   { id: 2, name: 'Rose' },
    //   { id: 3, name: 'Tom' },
    //   { id: 2, name: 'Jerry' }
    // ]

    /*
      思考:
        + find 多用于查找 [] 内存储的是复杂数据类型
        + 作用: 根据一个条件找到一条数据
        + 问题: 你为什么要找他 ?
          => 找到这条信息进行 增删改查
        + 如果 find 方法实现的是 深拷贝
          => 你的返回值和数组内的内容是两个 数据结构
          => 当你使用 返回值修改的时候, 数组内的数据不变
        + 最好的方案, 把数组中某一条数据的 地址 拿出来
          => 利用返回值修改的时候, 数组中对应的数据也会改变
    */

    // var user = arr.find(function (item) { return item.id === 2 })
    // user.name = '张思睿'
    // console.log(arr)
案例6 方法: every()
  • 语法: 数组.every(function (item, index, origin) {})
  • 返回值: 必然是一个 布尔值
    => 如果原始数组中每一个数据都满足条件, 返回的是 true
    => 只要有任何一个不满足条件, 返回值就是 false
    var arr = [ 100, 200, 300, 400, 500 ]
    // var res = arr.every(function (item) {
    //   console.log('执行')

    //   return item < 300
    // })
    // console.log(res)


    // Array.prototype.myEvery = function (cb) {
    //   // 从一堆内容中, 找到一个不对的, 就可以结束了
    //   // 1. 假设所有内容全部满足条件
    //   var flag = true

    //   // 2. 通过遍历数组来验证我的假设
    //   for (var i = 0; i < this.length; i++) {
    //     var r = cb(this[i], i, this)
    //     if (!r) {
    //       // 推翻我的假设
    //       flag = false
    //       break
    //     }
    //   }

    //   // 3. 返回我的假设
    //   return flag
    // }

    // var res = arr.myEvery(function (item) {
    //   console.log('执行')
    //   return item < 600
    // })
    // console.log(res)
案例7 方法: some()
  • 语法: 数组.some(function (item, index, origin) {})
  • 返回值: 必然是一个布尔值
    => 如果数组中有任意一个满足条件, 最终返回 true
    => 只有数组中所有数据都不满足条件, 最终返回 false
    // var arr = [ 100, 200, 300, 400, 500 ]
    // // var res = arr.some(function (item) {
    // //   console.log('执行')
    // //   return item > 100
    // // })
    // // console.log(res)

    // Array.prototype.mySome = function (cb) {
    //   // 1. 假设都不满足条件
    //   var flag = false

    //   // 2. 开始循环
    //   for (var i = 0; i < this.length; i++) {
    //     var r = cb(this[i], i, this)
    //     if (r) {
    //       flag = true
    //       break
    //     }
    //   }

    //   // 3. 定义返回值
    //   return flag
    // }

    // var res = arr.mySome(function (item) {
    //   console.log('执行')
    //   return item > 1000
    // })
    // console.log(res)
案例8 方法: reduce()
  • 语法: 数组.reduce(function (prev, item, index, origin) {}, init)
    => prev:
    -> 循环的第一次表示的是 init 初始值
    -> 循环的第二次开始表示的是 上一次的 结果
    => init: 表示叠加的初始值, 选填
    -> 如果你填写了 init, 方法内数组遍历的时候, 从 [0] 开始
    -> 如果你没有填写 init, 默认使用数组 [0] 数据来充当 init, 方法内遍历的时候从 [1] 开始遍历
    var arr = [ 10, 20, 30, 40, 50 ]
    console.log('原始数组 : ', arr)

    Array.prototype.myReduce = function (cb, init) {
      // 1. 决定一个遍历的开始位置
      var start = init !== undefined ? 0 : 1

      // 2. 判断 init 是否传递了, 来决定使用哪一个当做初始值
      init = init ?? this[0]

      // 3. 开始遍历
      for (var i = start; i < this.length; i++) {
        // 本次运算的结果
        var r = cb(init, this[i], i, this)

        // 修改 init
        // 思考: 当你给到回调函数内运算的时候, 把前一次的值, 和本次的值都给了
        //      在回调函数内已经进行完毕本次运算了
        //      r 就是本次运算的结果, 直接替换 init
        init = r
      }

      // 4. 循环结束, init 就是最终结果
      return init
    }

    // 使用的时候
    var r1 = arr.myReduce(function (prev, item) {
      console.log('prev : ', prev, ' --- ', 'item : ', item)
      return prev + item
    }, 0)
    console.log(r1)
    var r2 = arr.myReduce(function (prev, item) {
      console.log('prev : ', prev, ' --- ', 'item : ', item)
      return prev + item
    })
    console.log(r2)

    // var res = arr.reduce(function a(prev, item) {
    //   return prev + item
    // }, 0)
    // console.log(res)
    /*
      var res = arr.reduce(function a(prev, item) {
        return prev + item
      }, 0)

      根据 arr 数组的结构, a 函数会被执行 5 次
        + 第一次: init === 0
          => prev: 0
          => item: 10
          => return: 0 + 10
        + 第二次:
          => prev: 10
          => item: 20
          => return 10 + 20
        + 第三次:
          => prev: 30
          => item: 30
          => return: 30 + 30
    */

    /*
      var res = arr.reduce(function a(prev, item) {
        return prev + item
      })

      根据 arr 的数据结构和 reduce 的调用, a 函数会被执行 4 次
        + 第一次: init === 10
          => prev: 10
          => item: 20
          => return: 10 + 20
        + 第二次:
          => prev: 30
          => item: 30
          => return: 30 + 30
    */
案例9 封装范围内随机整数
  • 封装函数, 能根据参数给出一个范围内的随机整数
// 1. 封装函数, 求 0 ~ 10 之间的随机整数
/*
  概率问题:
    放大十倍以后的取之范围 [0, 10)
      + 0 ~ 0.499      0
      + 0.5 ~ 1.499    1
      + 8.5 ~ 9.499    9
      + 9.5 ~ 9.999    10
*/
// function fn() {
//   // 1. 拿到随机小数
//   // 取值范围 [0, 1)
//   var r1 = Math.random()

//   // 2. 放大 10 倍
//   // 取值范围 [0, 10)
//   var r2 = r1 * 10

//   // 3. 四舍五入
//   var res = Math.round(r2)

//   return res
// }


// function fn() {
//   // 1. 拿到随机小数
//   // 取值范围 [0, 1)
//   var r1 = Math.random()

//   // 2. 放大 10 倍
//   // 取值范围 [0, 11)
//   var r2 = r1 * (10 + 1)

//   // 3. 取整
//   // Math.ceil    => 取整之前 -0.999 ~ 9.999
//   // Math.floor   => 取整之前 0 ~ 10.999
//   var res = Math.floor(r2)

//   return res
// }


// 2. 求 0 ~ 20 之间的随机整数
// function fn() {
//   var r1 = Math.random()
//   var r2 = r1 * (20 + 1)
//   return Math.floor(r2)
// }


// 3. 求 10 ~ 30 之间的随机整数
// function fn() {
//   // 1. 求 0 ~ 10 之间的随机整数
//   var r1 = Math.floor(Math.random() * (20 + 1))

//   // 2. 用结果 + 10
//   return r1 + 10
// }

// 4. 求 min ~ max 之间的随机整数
// function fn(a, b) {
//   // 0. 判断大小
//   var min = Math.min(a, b)
//   var max = Math.max(a, b)

//   // 1. 求 0 ~ (max - min) 之间的随机整数
//   var r1 = Math.floor(Math.random() * (max - min + 1))

//   // 2. 加上 min
//   return r1 + min
// }


// 函数的参数默认值
//   在设计形参的时候, 给形参添加一个默认值
//   使用的时候, 如果你没有传递实参, 那么就用默认值
// function fn(a = 255, b = 0) {
//   return Math.floor(Math.random() * (Math.abs(a - b) + 1)) + Math.min(a, b)
// }

var obj = {}
for (var i = 0; i < 1000000; i++) {
  var res = fn(17)
  if (obj[res]) {
    obj[res]++
  } else {
    obj[res] = 1
  }
}
console.log(obj)
案例10 六位随机验证码
    // function randomCode() {
    //   // 准备一个验证码可以出现的内容
    //   var str = 'abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ0123456789'

    //   // 准备一个变量接受结果
    //   var res = ''

    //   // 拿出随机的一位
    //   for (var i = 0; i < 6; i++) {
    //     var s = randomNum(str.length - 1)
    //     res += str[s]
    //   }

    //   // 返回 res
    //   return res
    // }

    // var res = randomCode()
    // console.log(res)


    // 需求2: 随机的 6 位不重复的验证码
    // function randomCode() {
    //   // 准备一个验证码可以出现的内容
    //   var str = 'abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ0123456789'

    //   // 准备一个数组接受结果
    //   var res = []

    //   // 循环生成六个内容(不一定是六次)
    //   // 只要 res 的 length 小于 6, 就得再来一次
    //   while (res.length < 6) {
    //     // 向数组内添加一个内容
    //     var s = str[ randomNum(str.length - 1) ]

    //     // 一定要把 s 加进去吗 ?
    //     // 保证原始数组内没有内容的时候, 才添加
    //     if (res.indexOf(s) === -1) res.push(s)
    //   }

    //   // 制作返回值
    //   return res.join('')
    // }

    // var code = randomCode()
    // console.log(code)


    // 生成函数, 出现随机颜色字符串
    function randomColor() {
      // 组装一个随机数字的字符串
      return `rgb(${ randomNum() }, ${ randomNum() }, ${ randomNum() })`
    }

    console.log(randomColor())

    // document.body.style.backgroundColor = randomColor()
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值