【前端面试】七、算法-节流、柯里化、数组和集合

devtools/2024/12/22 15:35:05/

数组常用方法

  • forEach:遍历数组,对数组的每个元素执行一次提供的函数。

  • map:创建一个新数组,其结果是该数组中的每个元素是调用一次提供的函数后的返回值。

  • filter:创建一个新数组,其包含通过所提供函数实现的测试的所有元素。

  • reduce:对数组中的每个元素执行一个由您提供的reducer函数(升序执行),将其结果汇总为单个返回值。

数组去重

  • 使用Set:利用Set的自动去重特性,将数组转换为Set,再转换回数组。

  • 使用indexOf:通过遍历数组,检查当前元素是否已在结果数组中出现过(使用indexOf方法)。

  • 使用Map:利用Map对象的键是唯一的特性,通过遍历数组,将数组元素作为键存入Map,最后再从Map中获取所有键组成的数组。

常见的数据结构

  1. 线性表:数组、链表(单向链表、双向链表、循环链表)。

  2. 栈与队列:后进先出(LIFO)和先进先出(FIFO)的数据结构。

  3. 树与二叉树:二叉查找树、平衡二叉树(如AVL树、红黑树)、堆等。

  4. :用于表示多对多关系的数据结构,包括有向图和无向图。

设计模式

  1. 单例模式:确保一个类仅有一个实例,并提供一个全局访问点。

  2. 工厂模式:创建对象时不直接指定具体类,而是通过调用共同的接口来指定创建哪种类的实例。

  3. 观察者模式:定义对象间的一种一对多的依赖关系,当一个对象的状态发生改变时,所有依赖于它的对象都得到通知并被自动更新。

Promise.all的实现

function PromiseAll(promises) {  return new Promise((resolve, reject) => {  const results = [];  let count = 0;  promises.forEach((promise, index) => {  Promise.resolve(promise).then(  value => {  results[index] = value;  if (++count === promises.length) {  resolve(results);  }  },  error => {  reject(error);  }  );  });  });  
}

Event Emitter的实现(简化版):

class EventEmitter {  constructor() {  this.listeners = {};  }  on(event, callback) {  if (!this.listeners[event]) {  this.listeners[event] = [];  }  this.listeners[event].push(callback);  }  emit(event, ...args) {  if (this.listeners[event]) {  this.listeners[event].forEach(callback => callback(...args));  }  }  
}

<!DOCTYPE html>
<html lang="en">
<head><meta charset="UTF-8"><meta name="viewport" content="width=device-width, initial-scale=1.0"><title>Document</title>
</head>
<body><script>// 函数节流// 过滤重复滚动事件const throttle1 = (func, delay = 60) => {let lock = falsereturn (...args) => {if(lock) returnfunc(...args)lock = truesetTimeout(() => { lock = false }, delay)}}document.addEventListener('scroll',throttle1(console.log))// 过滤重复的验证事件(用户输入停止后300ms触发验证)const throttle2 = (func, delay = 300, I = null) => {return (...args) => {clearInterval(I)// I = setTimeout(() => func(...args), delay)I = setTimeout(func.bind(null,...args), delay)}}// 柯里化const curry1 = fn => {return  function curried(...args) {if(args.length >= fn.length) {// 参数足够,执行函数return fn.apply(this,args)} else {// 参数不足,返回一个函数继续收集剩余参数return (...args2) => {return curried.apply(this, args.concat(args2))}}}}const curry2 = func => {const g = (...allArgs) => allArgs.length >= func.length ? func(...allArgs) : (...args) => g(...allArgs, ...args)return g}/* math函数Math.abs:求绝对值Math.ceil:向上取整Math.floor:向下取整Math.round:四舍五入Math.max:求最大值Math.min:求最小值Math.pow:求幂Math.sqrt:求平方根Math.random:生成0-1之间的随机数Math.sign:判断正负,求数值符号 */// 判断素数const isPrime = num => {if(num <= 1) return falsefor(let i = 2; i <= Math.sqrt(num); i++) {if(num % i === 0) return false}return true}// n以内的素数function *sieve_primes(n) {let arr = Array.from({length: n - 2}, (item, index) => index + 2)while(arr.length > 0) {let prime = arr[0]yield primearr = arr.filter(num => num % prime !== 0)}}const it = sieve_primes(100)// console.log('100以内的素数=================');// console.log([...it]);/* 数组相关操作Array.length:长度Array.from:类数组转数组、创建数组Array.isArray:是否为数组Array.includes:是否包含某元素Array.indexOf:获取元素序号Array.concat:合并数组(元素)Array.slice:截取数组Array.splice:删除、插入、替换Array.push/pop/shift/unshift:入栈、出栈、出队、入队Array.join:数组转字符串Array.reverse:数组反转Array.sort:数组排序Array.filter:过滤Array.map:映射 1对1Array.reduce:累加 聚合 多对1Array.reduceRight:从右往左Array.some:是否有满足Array.every:是否全部满足Array.forEach:遍历 */// 数组去重const unique = arr => [...new Set(arr)]// 数组替换const arr1 = [1,2,3,4,5,6,7] // console.log('splice测试=================');// console.log(arr1.splice(2,2,'x')); // [3,4]// console.log(arr1); // [1,2,'x',5,6,7] // console.log(arr1.splice(2,1)); // ['x']arr1.splice(2,0,'y')// console.log(arr1); // [1,2,'y',5,6,7] // 括号匹配const is_balance = str => {const [first, ...others] = strconst stack = [first]while (others.length > 0) {const n = others.shift()const c = stack[stack.length - 1]const ifMatch =  (c === '(' && n === ')') || (c === '[' && n === ']') || (c === '{' && n === '}')ifMatch ? stack.pop() : stack.push(n)return stack.length === 0}}const students = [  {  id: 1,  name: "Alice",  score: 92,  groupId: 1,  },  {  id: 2,  name: "Bob",  score: 55,  groupId: 2,  },  {  id: 3,  name: "Charlie",  score: 88,  groupId: 1,  },  {  id: 4,  name: "David",  score: 76,  groupId: 3,  },  {  id: 5,  name: "Eva",  score: 62,  groupId: 2,  }  ];  const groups = [  { id: 1, name: "Math Group" },  { id: 2, name: "Science Group" },  { id: 3, name: "History Group" }  ];  // 投射const studentWithGrade = students.map(student => {return {...student,grade: student.score >= 60 ? '及格' : '不及格'}})// console.log('投射测试=================');// console.log(studentWithGrade);// 过滤const passedStudents = students.filter(student => student.score >= 60)// console.log('passedStudents 测试=================');// console.log(passedStudents);const group1Students = students.filter(student => student.groupId === 1)// console.log('group1Students 测试=================');// console.log(group1Students);// 分组const studentInGroups = students.reduce((groups, student) =>{groups[student.groupId] = [...(groups[student.groupId] || []), student]return groups},{})// console.log('studentInGroups 测试=================');// console.log(studentInGroups);// 联合const studentWithGroupInfo = students.map(student => {return {...student,groupInfo: groups.find(group => group.id === student.groupId)}})// console.log('studentWithGroupInfo 测试=================');// console.log(studentWithGroupInfo);// 排序 Array.prototype.sort 方法会对原数组进行排序const sortedByScoreAsc = students.slice().sort((a, b) => a.score - b.score);// console.log('sortedByScoreAsc 测试=================');// console.log(sortedByScoreAsc);const sortedByScoreDesc = students.slice().sort((a, b) => b.score - a.score);// console.log('sortedByScoreDesc 测试=================');// console.log(sortedByScoreDesc);const nameArr = ['张三','李四','王五'].sort((a,b) => a.localeCompare(b, 'zh'))// console.log('nameArr 测试=================');// console.log(nameArr);/* 集合操作 new Set([...arr])Set.add(element):添加元素Set.delete(element):删除元素Set.has(element):是否包含元素Set.clear():清空集合Set.size:集合长度Set.values():返回Iterator对象 */// 子数组和整除// 写一个函数solve(arr, N),判断数组arr中某一项,或任意多项的和,是否被另一个整数N整除// 例如:solve([1,2,3,4,5], 7) => true// 求数组全部组合后求余数const solve = (arr, N) => {const s = new Set()for(let i = 0; i <= arr.length; i++) {for (let j = i + 1; j <= arr.length; j++) {const remain = arr.slice(i, j).reduce((a,b) => a + b, 0) % Ns.add(remain)}}return s.has(0)}// 子问题结构思想const solve2 = (arr, N) => {const s = new Set()while (arr.length > 0) {const ak = arr.pop()s.add(ak)s.forEach(item => {s.add((item + ak) % N)})}return s.has(0)}// console.log('子数组和整除 测试=================');// console.log(solve2([1,2,3,4,5], 7));// console.log(solve2([3,9], 9));// 笛卡尔积// 例如[1,2] X ['a', 'b'] = [[1, 'a'], [1, 'b'], [2, 'a'], [2,'b']]function cartesianProduct(...Matrix) {if(Matrix.length ===0) return []if(Matrix.length === 1)return Matrix[0]let i = 0return Matrix.reduce((A,B) => {const product=[]for(let i=0; i<A.length; i++){for(let j=0; j<B.length; j++){product.push(Array.isArray(A[i]) ? [...A[i], B[j]] : [A[i], B[j]])}}return product})}result = cartesianProduct([1, 2], ['a', 'b']);  console.log(result); // [[1, 'a'], [1, 'b'], [2, 'a'], [2, 'b']]</script></body>
</html>


http://www.ppmy.cn/devtools/86553.html

相关文章

蓝牙网关厂家推荐:北京桂花网科技有限公司

在物联网技术日新月异的今天&#xff0c;蓝牙网关作为连接蓝牙设备与物联网系统的关键桥梁&#xff0c;其重要性日益凸显。在众多蓝牙网关厂家中&#xff0c;北京桂花网科技有限公司&#xff08;Cassia Networks&#xff09;以其卓越的技术实力、丰富的产品线和广泛的应用场景&…

QUIC 协议

详解 QUIC 协议&#xff1a;它为何比 TCP 更优越&#xff1f;

深度学习的矩阵计算

切片slice 在NumPy中&#xff0c;切片&#xff08;slicing&#xff09;是一种选择数组元素子集的方法。切片操作基于索引&#xff0c;但允许你指定一个范围的索引&#xff0c;而不是单个索引。这对于处理多维数组&#xff08;NumPy中的ndarray对象&#xff09;特别有用。 一维数…

【AI落地应用实战】DAMODEL深度学习平台部署+本地调用ChatGLM-6B解决方案

ChatGLM-6B是由清华大学和智谱AI开源的一款对话语言模型&#xff0c;基于 General Language Model (GLM)架构&#xff0c;具有 62亿参数。该模型凭借其强大的语言理解和生成能力、轻量级的参数量以及开源的特性&#xff0c;已经成为在学术界和工业界引起了广泛关注。 本篇将介…

kafka详解及应用场景介绍

Kafka架构 Kafka架构&#xff0c;由多个组件组成&#xff0c;如下图所示&#xff1a; 主要会包含&#xff1a;Topic、生产者、消费者、消费组等组件。 服务代理&#xff08;Broker&#xff09; Broker是Kafka集群中的一个节点&#xff0c;每个节点都是一个独立的Kafka服务器…

【MySQL】索引 【下】{聚簇索引VS非聚簇索引/创建主键索引/全文索引的创建/索引创建原则}

文章目录 1.聚簇索引 VS 非聚簇索引经典问题 2.索引操作创建主键索引唯一索引的创建普通索引的创建全文索引的创建查询索引删除索引索引创建原则 1.聚簇索引 VS 非聚簇索引 之前介绍的将所有的数据都放在叶子节点的这种存储引擎对应的就是 InnoDB 默认存储表数据的存储结构。 …

Docker中安装Kafka和Kafka UI管理界面

Kafka 简介 Apache Kafka 是一个分布式流处理平台,主要用于构建实时数据管道和流应用。它最初由LinkedIn开发,并于2011年开源,之后成为Apache项目的一部分。Kafka的核心概念和功能包括: 发布与订阅消息系统:Kafka允许用户发布和订阅消息流。高吞吐量:Kafka能够处理大量数…

【Gin】智慧架构的巧妙砌筑:Gin框架中控制反转与依赖注入模式的精华解析与应用实战(下)

【Gin】智慧架构的巧妙砌筑&#xff1a;Gin框架中控制反转与依赖注入模式的精华解析与应用实战(下) 大家好 我是寸铁&#x1f44a; 【Gin】智慧架构的巧妙砌筑&#xff1a;Gin框架中控制反转与依赖注入模式的精华解析与应用实战(下)✨ 喜欢的小伙伴可以点点关注 &#x1f49d; …