js知识和算法题

1.reduce方法

  <script>
    // Math.pow(m,n)->m^n就是求m的n次方方法是Math.pow
    // [].reduce((pre,cur,index,array)=>{
    //   pre上一次的值,cur当前循环的值,index是当前索引值,array当前数组,c是初始化值,传的化就是pre为c不传,就是pre为array[0]的值
    // },c)
    [3, 2, 1].reduce(Math.pow)//9求Math.pow的求平方的
    [3].reduce(Math.pow)//3-Math.pow不执行,callback不执行
    // [].reduce(Math.pow, 3)//3  Math.pow不执行,callback不执行
    // [].reduce(Math.pow)//undefined   . error
  </script>

2.js求素数


    // js求素数
    function isDel(n) {
      if (n == 1) {
        return false
      }
      if (n == 2) { return true }
      for (let i = 2; i < n; i++) {
        if (n % i === 0) {
          return false
        }
      }
      return true
    }
    // 1-100
    const result = []
    for (let j = 1; j <= 100; j++) {
      if (isDel(j)) {
        result.push(j)
      }
    }
    // 求平方根Math.sqrt(n)求平方根就是n的平方根
    console.log(result)

 3.fill数组填充

// fill数组填充的坑
    Array.from({ length: 3 }).fill(0)// [0, 0, 0]
    const c = [1, 2, 3]
    Array.from({ length: 3 }).fill(c)//[Array(3), Array(3), Array(3)]
    c[1] = 'dai'
    Array.from({ length: 3 }).fill(c)
    // 用双层for循环来构造二维数组
    let arr = []
    for (let i = 0; i < 3; i++) {
      const tem = []
      for (let j = 0; j < 3; j++) {
        // tem[0]=0,tem[1]=0,tem[2]=0
        tem[j] = 0
      }
      // arr[0]=[tem],
      arr[i] = tem
      // 修改arr第一个索引数组的第一个值
      arr[0][0] = 1
      console.log(arr)
    }

4.逻辑运算符

// 运算符
    let a = 0
    let b = 1
    let c = b.value?.v
    a ||= 10
    b &&= 2
    c ??= 5
    console.log(a)//10
    console.log(b)//2
    console.log(c)
    console.log(a + b + c)//17
    console.log(11 ?? 1)//11
    // 双问号运算符只判断null和undefined

 5数组中找到与目标值最接近的数字

const arr = [1, 3, 5, 6, 10]
    // 方法1
    function getClosestNumber(array, target) {
      let result = array[0]
      for (let i = 0; i < array.length; i++) {
        if (Math.abs(array[i] - target) < Math.abs(result - target)) {
          result = array[i]
        }
      }
      return result
    }
    // 方法2
    function getClosestNumber(array, target) {
      return array.reduce((pre, cur) => {
        return Math.abs(pre - target) < Math.abs(cur - target) ? pre : cur
      })
    }
    const res1 = getClosestNumber(arr, 7)//6
    const res2 = getClosestNumber(arr, 3)//3
    console.log('res1:', res1)
    console.log('res2:', res2)const arr = [1, 3, 5, 6, 10]
    // 方法1
    function getClosestNumber(array, target) {
      let result = array[0]
      for (let i = 0; i < array.length; i++) {
        if (Math.abs(array[i] - target) < Math.abs(result - target)) {
          result = array[i]
        }
      }
      return result
    }
    // 方法2
    function getClosestNumber(array, target) {
      return array.reduce((pre, cur) => {
        return Math.abs(pre - target) < Math.abs(cur - target) ? pre : cur
      })
    }
    const res1 = getClosestNumber(arr, 7)//6
    const res2 = getClosestNumber(arr, 3)//3
    console.log('res1:', res1)
    console.log('res2:', res2)

6. 遍历对象的方式

 // 遍历对象的方式有5种for   in     Object.keys()   Object.getOwnPropertyNames()  Object.getOwnPropertySymbols()   Reflect.ownKeys()
    // 原型属性
    const obj = Object.create({ bar: 'bar' })
    // 对象可 枚举属性
    obj.foo = 'foo'
    // 对象不可枚举属性
    Object.defineProperty(obj, 'name', {
      enumerable: false,
      value: 'kex'
    })
    // Symbol属性
    obj[Symbol('age')] = 'age'
    for (let key in obj) {
      console.log(key, obj[key])//foo foo  bar bar 
    }
    Object.keys(obj)//['foo']
    // Object.getOwnPropertyNames()获取对象自身的所以属性名,包括不可枚举的属性,不包含原型链上的属性和symbol属性
    //  Reflect.ownKeys(),所以的对象所有的属性都输出出来

7. 把稀疏数组变成密集数组的方法

// 稀疏数组和密集数组
    // 密集数组是数组元素之间紧密相连,稀疏数组数组之间存在间隙
    const arr = [1, 2, 3]
    const arr1 = [1, 2, 3]
    arr1[8] = 8
    // arr1
    console.log(arr1)//[1, 2, 3, empty × 5, 8]length=9
    // 把稀疏数组变成密集数组的方法
    const arr4 = new Array(3)//稀疏数组
    const arr5 = Array.apply(null, Array(3))//密集数组[undefined,undefined,undefined]
    const arr6 = Array.from({ length: 3 }, () => { })//密集数组 [undefined, undefined, undefined]
    //  密集数组的1-10的方法
    Array.from({ length: 10 }).map((x, i) => i + 1)// [1, 2, 3, 4, 5, 6, 7, 8, 9, 10]得到1-10的数组
    Array.apply(null, Array(10)).map((x, i) => i + 1)//[1, 2, 3, 4, 5, 6, 7, 8, 9, 10]得到1-10的数组

 8.数组1到n中1出现的次数

// 整体思想:以字符串形势进行遍历
    //方法1: 将数字转换为字符串,使用正则匹配其中出现的1的数量
    // 方法2:将数字转换为字符串,再转换为数组,通过filter方法过滤出1的值
    // 方法1
    function findOne(n) {
      return Array.from({ length: n }).map((v, i) => i + 1).reduce((pre, cur) => {
        const curCount = String(cur).match(/1/g)?.length || 0
        return pre + curCount
      }, 0)
    }
    findOne(10)//2
    findOne(20)//12
    findOne(2000)
    // 方法2
    function findOne2(c) {
      return Array.from({ length: c }).map((v, i) => i + 1).reduce((pre, cur) => {
        const cumt = String(cur).split('').filter((i) => i === '1').length
        return pre + cumt
      }, 0)
    }
    findOne2(10)
    findOne2(20)

9.设计一个任务队列并控制并发数

// 同时执行任务数为10个
    // 释放任务队列空间
    // promise的执行函数
    function createTask(i) {
      return () => {
        return new Promise((resolve, reject) => {
          setTimeout(() => {
            resolve(i)
          }, 2000)
        })
      }
    }
    // 执行的10个任务
    class TaskQueue {
      constructor() {
        this.max = 10
        this.taskList = []
        setTimeout(() => {
          this.run()
        })
      }
      // 添加任务队列
      addTask(task) {
        this.taskList.push(task)
      }
      //  自动执行run方法
      run() {
        const length = this.taskList.length
        if (!length) {
          return
        }
        const min = Math.min(this.max, length)
        for (let i = 0; i < min; i++) {
          this.max--
          const task = this.taskList.shift()
          task().then(res => {
            console.log(res)
          }).catch(error => {
            console.log(error)
          }).finally(() => {
            this.max++
            this.run()
          })
        }
      }
    }

    const taskQueue = new TaskQueue()
    for (let i = 0; i < 20; i++) {
      const task = createTask(i)
      taskQueue.addTask(task)
    }

10.求出n个连续数组的最大和

 

// 求n个连续数组的最大和
    // 求和函数
    function arrSum(arr) {
      return arr.reduce((pre, cur) => pre + cur)
    }
    // 截取数组函数并比较大小
    function getMax(arr, n) {
      let left = 0
      let right = left + n
      let max = arrSum(arr.slice(left, right))
      for (; right <= arr.length; left++, right++) {
        const curSum = arrSum(arr.slice(left, right))
        max = Math.max(curSum, max)
      }
      return max
    }
    const arr = [2, 5, 3, 4, 6]
    const res1 = getMax(arr, 2)//10
    const res2 = getMax(arr, 3)//13
    console.log(res1)
    console.log(res2)

11.考察this指向问题

// 考察this指向问题
    // this=函数的调用者
    // arguments=函数实际传递的参数
    var length = 1
    function fn() {
      console.log(this.length)
    }
    var obj = {
      length: 100,
      action: function (callback) {
        // 输出1
        callback() //this->window->1
        // 输出2,因为有5个参数[fn,1, 2, 3, 4]
        arguments[0]()//输出5
        // 输出3
        var foo = arguments[0]
        foo()//this指向的是window输出1
        // 输出4
        this.foo2 = arguments[0]
        this.foo2()//this的指向为obj,obj的length长度为100,所以输出为100
      }
    }
    var arr1 = [1, 2, 3, 4]
    obj.action(fn, ...arr1)
    // 引题
    var length = 1;
    function foo() {
      console.log(this.length)
    };
    var arr2 = [foo, 2, 3];
    console.log(arr2[0]())
    arr2[0]();//foo this->arr2->3
    var f1 = arr2[0] // f1前面没有载体,this指向window 结果为1
    f1()

12.计算对象的层数(递归运算)

    const obj = {
      a: 'a',
      b: {
        c: {
          d: 'd',
          e: 'e',
        }
      },
      f: {
        g: {
          h: {
            i: 'i',
          }
        },
      }
    }
function getLEvel(obj) {
      let result1 = 1
      function fn(param, level = 0) {
        if (typeof param === 'object' && param !== null) {
          Object.values(param).forEach(item => {
            if (typeof item === 'object' && item !== null) {
              fn(item, level + 1)
            } else {
              result1 = level + 1 > result1 ? level + 1 : result1
            }
          })
        } else {
          result1 = level > result1 ? level : result1
        }
      }
      fn(obj)
      return result1
    }
    console.log(getLEvel(obj))

13.函数柯里化

// 函数柯里化
    // reduce求和
    function argsSum(args) {
      return args.reduce((pre, cur) => {
        return pre + cur
      }, 0);
    }
    const foo = (...args1) => {
      const sum1 = argsSum(args1)
      const fu = (...args2) => {
        const sum2 = argsSum(args2)
        return foo(sum1 + sum2)
      }
      // 返回一个函数
      fu.toString = () => {
        return sum1;
      }
      return fu
    }
    // foo(1,2,3)==6;
    console.log(foo(1, 2, 3) == 6)

    console.log(foo(1)(2, 3) == 6)
    console.log(foo(1)(2)(4)(3) == 10)

 

 

 

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值