leetcode — JavaScript专题(五):计数器 II、只允许一次函数调用、 创建 Hello World 函数、将对象数组转换为矩阵、节流、分块数组

专栏声明:只求用最简单的,容易理解的方法通过,不求优化,不喜勿喷

2665. 计数器 II

题面

请你写一个函数 createCounter. 这个函数接收一个初始的整数值 init 并返回一个包含三个函数的对象。

这三个函数是:

increment() 将当前值加 1 并返回。
decrement() 将当前值减 1 并返回。
reset() 将当前值设置为 init 并返回。

知识点:

闭包

思路

编写一个闭包保存我们的变量的当前数值,之后对于不同的操作对这个数据进行增减即可,注意 init 作为我们传入的数值,也可以作为一个闭包中可以获取和操作的数值

代码
var createCounter = function(init) {
    
    
     var now = init;
     let increment = () => {
    
    
         return ++now;
     }
     let decrement = () => {
    
    
         return --now;
     }
     let reset = () => {
    
    
         return now = init;
     }
     return {
    
    increment,decrement,reset }
};

/**
 * const counter = createCounter(5)
 * counter.increment(); // 6
 * counter.reset(); // 5
 * counter.decrement(); // 4
 */

2666. 只允许一次函数调用

题面

给定一个函数 fn ,它返回一个新的函数,返回的函数与原始函数完全相同,只不过它确保 fn 最多被调用一次。

第一次调用返回的函数时,它应该返回与 fn 相同的结果。
第一次后的每次调用,它应该返回 undefined 。

知识点:

闭包

思路

我们设定一个变量标识这个函数是不是运行过了,之后每次调用的时候判定,如果调用过了就返回 undefined ,否则返回函数的执行结果即可

代码
var once = function(fn) {
    
    

    var first = 0;
    return function(...args){
    
    
        if(first == 0){
    
    
              first++;
            return fn(...args)
        }else{
    
    
            return undefined
        }
    }
};

2667. 创建 Hello World 函数

题面

请你编写一个名为 createHelloWorld 的函数。它应该返回一个新的函数,该函数总是返回 “Hello World” 。

知识点:

思路

返回 “Hello World” 即可,纯弱智

代码
var createHelloWorld = function() {
    
    
    return function(...args) {
    
    
        return "Hello World";
    }
};

/**
 * const f = createHelloWorld();
 * f(); // "Hello World"
 */

2675. 将对象数组转换为矩阵

题面

编写一个函数,将对象数组 arr 转换为矩阵 m 。

arr 是一个由对象组成的数组或一个数组。数组中的每个项都可以包含深层嵌套的子数组和子对象。它还可以包含数字、字符串、布尔值和空值。

矩阵 m 的第一行应该是列名。如果没有嵌套,列名是对象中的唯一键。如果存在嵌套,列名是对象中相应路径,以点号 “.” 分隔。

剩余的每一行对应 arr 中的一个对象。矩阵中的每个值对应对象中的一个值。如果给定对象在给定列中没有值,则应该包含空字符串 “” 。

矩阵中的列应按 字典升序 排列。

知识点:

深度优先遍历、set、哈希表

思路

dfs递归遍历给出的对象,用一个 path 数组保存已经经过的路径,方便生成 key

  • 如果遇到的是基础类型,直接把 key 和 value 进行保存
  • 如果是数组类型,对数组的每一项进行dfs 遍历,并将 index 放入路径参数中
  • 如果是对象类型,对对象的每个 key 进行 dfs 遍历,并将 key 放入路径参数中
    遍历完成后,遍历每一行的 map,获取所有的 key 的信息,之后重新遍历我们每一行的map,对每个 key 获取信息,生成我们需要的结果返回即可
代码
type Value = string | number | boolean | null

function jsonToMatrix(arr: any[]): Value[][] {
    
    
  const rows: Map<string, Value>[] = []

  arr.forEach(item => {
    
    
    const rowMap = new Map<string, Value>()
    dfs(item, [], rowMap)
    rows.push(rowMap)
  })

  const allKey = new Set<string>()
  rows.forEach(mp => {
    
    
    for (const key of mp.keys()) {
    
    
      allKey.add(key)
    }
  })
  const row0 = [...allKey].sort()

  const res: Value[][] = Array(arr.length + 1)
  res[0] = row0
  for (let i = 1; i < res.length; i++) {
    
    
    res[i] = Array(allKey.size).fill('')
    for (let j = 0; j < row0.length; j++) {
    
    
      const mp = rows[i - 1]
      if (mp.has(row0[j])) {
    
    
        res[i][j] = mp.get(row0[j])!
      }
    }
  }
  return res

  function dfs(obj: any, path: string[], rowMap: Map<string, Value>): void {
    
    
    if (!isObject(obj)) {
    
    
      const key = path.join('.')
      rowMap.set(key, obj)
      return
    }

    if (Array.isArray(obj)) {
    
    
      obj.forEach((item, index) => {
    
    
        path.push(String(index))
        dfs(item, path, rowMap)
        path.pop()
      })
    }

    Object.entries(obj).forEach(([key, val]) => {
    
    
      path.push(key)
      dfs(val, path, rowMap)
      path.pop()
    })
  }
}

function isObject(val: unknown): val is object {
    
    
  return typeof val === 'object' && val !== null
}

2676. 节流

题面

现给定一个函数 fn 和一个以毫秒为单位的时间 t ,请你返回该函数的 节流 版本。

节流 函数首先立即被调用,然后在 t 毫秒的时间间隔内不能再次执行,但应该存储最新的函数参数,以便在延迟结束后使用这些参数调用 fn 。

知识点:

节流

思路

我们设定一个变量记录我们上一轮的运行的时间,每当我们有新的任务调用时,如果它已经比上一轮调用晚了 t 时间以上,我们直接运行这个任务,然后记录当前时间为上一轮运行时间;
如果我们当前任务还不能执行,我们通过上一轮执行时间和当前时间的差以及 t 的值算出它需要推迟多久,开始一个计数器,在这段时间后执行我们的函数,我们保存这个计时器,方便我们取消;
每次开始计时器的时候,我们要取消已经存在的计时器,也就是取消上一次的任务,以便于每次都能执行最新的任务。

代码
var throttle = function (fn, t) {
    
    
    let timer = null;
    let mt = 0;
    return function (...args) {
    
    
        let now = Date.now();
        if (now - mt > t) {
    
    
            mt = now;
            fn(...args)
        }else{
    
    
            clearTimeout(timer);
            timer = setTimeout(() => {
    
    
                mt += t ;
                fn(...args)
            },  t - now + mt)
        }
    }
};

/**
 * const throttled = throttle(console.log, 100);
 * throttled("log"); // logged immediately.
 * throttled("log"); // logged at t=100ms.
 */

2677. 分块数组

题面

给定一个数组 arr 和一个块大小 size ,返回一个 分块 的数组。分块 的数组包含了 arr 中的原始元素,但是每个子数组的长度都是 size 。如果 arr.length 不能被 size 整除,那么最后一个子数组的长度可能小于 size 。

你可以假设该数组是 JSON.parse 的输出结果。换句话说,它是有效的JSON。

请你在不使用 lodash 的函数 _.chunk 的情况下解决这个问题。

知识点:

数组

思路

遍历原数组,将元素依次放入临时数组中,到达指定长度就将临时数组放进我们的结果数组并且清空临时数组,最后把剩下的元素(如果还有的话)一起放入结果数组,返回结果即可

代码
var chunk = function(arr, size) {
    
    
    let re = [ ];
    let t = [];
    for(var i = 0;i< arr.length;i++){
    
    
        if(t.length == size){
    
    
            re.push([...t]);
            t = [];
        }
        t.push(arr[i]);
    }
    if(t.length != 0){
    
    
        re.push([...t]);
    }
    return re;
};

猜你喜欢

转载自blog.csdn.net/weixin_46463785/article/details/130761536
今日推荐