赞
踩
add(1); // 1
add(1)(2); // 3
add(1)(2)(3);// 6
add(1)(2, 3); // 6
add(1, 2)(3); // 6
add(1, 2, 3); // 6
function add(...args) { // 在内部声明一个函数,利用闭包的特性保存并收集所有的参数值 let fn = function(...newArgs) { return add.apply(null, args.concat(newArgs)) } // 利用toString隐式转换的特性,当最后执行时隐式转换,并计算最终的值返回 fn.toString = function() { return args.reduce((total,curr)=> total + curr) } return fn }
考点:
toSting()
方法// 测试,调用toString方法触发求值
add(1).toString(); // 1
add(1)(2).toString(); // 3
add(1)(2)(3).toString();// 6
add(1)(2, 3).toString(); // 6
add(1, 2)(3).toString(); // 6
add(1, 2, 3).toString(); // 6
首先:我知道多少种去重方式
1. 双层 for 循环
function distinct(arr) { for (let i=0, len=arr.length; i<len; i++) { for (let j=i+1; j<len; j++) { if (arr[i] == arr[j]) { arr.splice(j, 1); // splice 会改变数组长度,所以要将数组长度 len 和下标 j 减一 len--; j--; } } } return arr; }
思想: 双重
for
循环是比较笨拙的方法,它实现的原理很简单:先定义一个包含原始数组第一个元素的数组,然后遍历原始数组,将原始数组中的每个元素与新数组中的每个元素进行比对,如果不重复则添加到新数组中,最后返回新数组;因为它的时间复杂度是O(n^2)
,如果数组长度很大,效率会很低
2. Array.filter() 加 indexOf/includes
function distinct(a, b) {
let arr = a.concat(b);
return arr.filter((item, index)=> {
//return arr.indexOf(item) === index
return arr.includes(item)
})
}
思想: 利用
indexOf
检测元素在数组中第一次出现的位置是否和元素现在的位置相等,如果不等则说明该元素是重复元素
3. ES6 中的 Set 去重
function distinct(array) {
return Array.from(new Set(array));
}
思想: ES6 提供了新的数据结构 Set,Set 结构的一个特性就是成员值都是唯一的,没有重复的值。
4. reduce 实现对象数组去重复
var resources = [ { name: "张三", age: "18" }, { name: "张三", age: "19" }, { name: "张三", age: "20" }, { name: "李四", age: "19" }, { name: "王五", age: "20" }, { name: "赵六", age: "21" } ] var temp = { }; resources = resources.reduce((prev, curv) => { // 如果临时对象中有这个名字,什么都不做 if (temp[curv.name]) { }else { // 如果临时对象没有就把这个名字加进去,同时把当前的这个对象加入到prev中 temp[curv.name] = true; prev.push(curv); } return prev }, []); console.log("结果", resources);
这种方法是利用高阶函数
reduce
进行去重, 这里只需要注意initialValue
得放一个空数组[],不然没法push
观察者模式(基于发布订阅模式) 有观察者,也有被观察者
观察者需要放到被观察者中,被观察者的状态变化需要通知观察者 我变化了 内部也是基于发布订阅模式,收集观察者,状态变化后要主动通知观察者
class Subject { // 被观察者 学生 constructor(name) { this.state = 'happy' this.observers = []; // 存储所有的观察者 } // 收集所有的观察者 attach(o){ // Subject. prototype. attch this.observers.push(o) } // 更新被观察者 状态的方法 setState(newState) { this.state = newState; // 更新状态 // this 指被观察者 学生 this.observers.forEach(o => o.update(this)) // 通知观察者 更新它们的状态 } } class Observer{ // 观察者 父母和老师 constructor(name) { this.name = name } update(student) { console.log('当前' + this.name + '被通知了', '当前学生的状态是' + student.state) } } let student = new Subject('学生'); let parent = new Observer('父母'); let teacher = new Observer('老师'); // 被观察者存储观察者的前提,需要先接纳观察者 student. attach(parent); student. attach(teacher); student. setState('被欺负了');
链表结构
看图理解next层级
// 链表 从头尾删除、增加 性能比较好 // 分为很多类 常用单向链表、双向链表 // js模拟链表结构:增删改查 // node节点 class Node { constructor(element,next) { this.element = element this.next = next } } class LinkedList { constructor() { this.head = null // 默认应该指向第一个节点 this.size = 0 // 通过这个长度可以遍历这个链表 } // 增加O(n) add(index,element) { if(arguments.length === 1) { // 向末尾添加 element = index // 当前元素等于传递的第一项 index = this.size // 索引指向最后一个元素 } if(index < 0 || index > this.size) { throw new Error('添加的索引不正常') } if(index === 0) { // 直接找到头部 把头部改掉 性能更好 let head = this.head this.head = new Node(element,head) } else { // 获取当前头指针 let current = this.head // 不停遍历 直到找到最后一项 添加的索引是1就找到第0个的next赋值 for (let i = 0; i < index-1; i++) { // 找到它的前一个 current = current.next } // 让创建的元素指向上一个元素的下一个 // 看图理解next层级 current.next = new Node(element,current.next) // 让当前元素指向下一个元素的next } this.size++; } // 删除O(n) remove(index) { if(index < 0 || index >= this.size) { throw new Error('删除的索引不正常') } this.size-- if(index === 0) { let head = this.head this.head = this.head.next // 移动指针位置 return head // 返回删除的元素 }else { let current = this.head for (let i = 0; i < index-1; i++) { // index-1找到它的前一个 current = current.next } let returnVal = current.next // 返回删除的元素 // 找到待删除的指针的上一个 current.next.next // 如删除200, 100=>200=>300 找到200的上一个100的next的next为300,把300赋值给100的next即可 current.next = current.next.next return returnVal } } // 查找O(n) get(index) { if(index < 0 || index >= this.size) { throw new Error('查找的索引不正常') } let current = this.head for (let i = 0; i < index; i++) { current = current.next } return current } } var ll = new LinkedList() ll.add(0,100) // Node { ellement: 100, next: null } ll.add(0,200) // Node { element: 200, next: Node { element: 100, next: null } } ll.add(1,500) // Node {element: 200,next: Node { element: 100, next: Node { element: 500, next: null } } } ll.add(300) ll.remove(0) console.log(ll.get(2),'get') console.log(ll.head) module.exports = LinkedList
第一版 时间复杂度为 O(n^2)
function getTenNum(testArray, n) { let result = []; for (let i = 0; i < n; ++i) { const random = Math.floor(Math.random() * testArray.length); const cur = testArray[random]; if (result.includes(cur)) { i--; break; } result.push(cur); } return result; } const testArray = [1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14]; const resArr = getTenNum(testArray, 10);
第二版 标记法 / 自定义属性法 时间复杂度为 O(n)
function getTenNum(testArray, n) { let hash = { }; let result = []; let ranNum = n; while (ranNum > 0) { const ran = Math.floor(Math.random() * testArray.length); if (!hash[ran]) { hash[ran] = true; result.push(ran); ranNum--; } } return result; } const testArray = [1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14]; const resArr = getTenNum(testArray, 10);
第三版 交换法 时间复杂度为 O(n)
function getTenNum(testArray, n) {
const cloneArr = [...testArray];
let result = [];
for (let i = 0; i < n; i++) {
debugger;
const ran = Math.floor(Math.random() * (cloneArr.length - i));
result.push(cloneArr[ran]);
cloneArr[ran] = cloneArr[cloneArr.length - i - 1];
}
return result;
}
const testArray = [1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14];
const resArr = getTenNum(testArray, 14);
值得一提的是操作数组的时候使用交换法 这种思路在算法里面很常见
最终版 边遍历边删除 时间复杂度为 O(n)
function getTenNum(testArray, n) {
const cloneArr = [...testArray];
let result = [];
for (let i = 0; i < n; ++i) {
const random = Math.floor(Math.random() * cloneArr.length);
const cur = cloneArr[random];
result.push(cur);
cloneArr.splice(random, 1);
}
return result;
}
const testArray = [1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14];
const resArr = getTenNum(testArray, 14);
基础的html
代码:
<html> <style> html, body { margin: 0; height: 100%; } ul { list-style: none; margin: 0; padding: 0; display: flex; justify-content: center; } .b
Copyright © 2003-2013 www.wpsshop.cn 版权所有,并保留所有权利。