集合

集合是由一组无序且唯一的项组成。这个数据结构使用了与有限集合相同的数学概念。

创建一个集合

function Set(){var items = {};
}

集合的方法

add(value) -- 向集合添加一个新的项
remove(value) -- 从集合移除一个值
has(value) -- 如果值在集合中,返回true,否则返回false
clear() -- 移除集合中的所有项
size() -- 返回集合所包含元素的数量
values() -- 返回一个包含集合中所有值的数值

完整的集合代码

function Set(){var items = {};this.has = function(value){return items.hasOwnProperty(value);};this.add = function(value) {if(!this.has(value)){items[value] = value;return true; }return false;};this.remove = function(value) {if(this.has(value)){delete items[value];return true;}return false;};this.clear = function() {items = {};};this.size = function () {return Object.keys(items).length;};this.values = function(){return Object.keys(items);};}

集合操作

并集--对于给定的两个集合,返回一个包含两个集合中所有元素的新集合。

this.union = function(otherSet) {var unionSet = new Set();var values = this.values();for(var i=0;i<values.length;i++){unionSet.add(value[i]);}values = otherSet.values();for(var i=0;i<values.length;i++) {unionSet.add(values[i]);}return unionSet;
}

交集 -- 集合A和B的交集是元素存在于A中,其存在于B中。

this.intersection = function(otherSet) {var intersectionSet = new Set();var values = this.values();for(var i=0;i<values.length;i++){if(otherSet.has(values[i])){intersectionSet.add(values[i]);}}return intersectionSet;
}

差集 -- 集合A和B的差集,是元素存在于A中,且元素不存在于B中。

this.difference = function(otherSet){var differenceSet = new Set();var values = this.values();for(var i=0; i<values.length;i++){if(!otherSet.has(value[i)){differenceSet.add(values[i]);}}return differenceSet;
}

ES6中的Set & WeakSet

ES6的标准中实现了Set的数据结构,它可以这样被使用。

const s = new Set();[2, 3, 5, 4, 5, 2, 2].forEach(x => s.add(x));for (let i of s) {console.log(i);
}
// 2 3 5 4

Set 实例的属性和方法

Set 结构的实例有以下属性。

  • Set.prototype.constructor:构造函数,默认就是Set函数。

  • Set.prototype.size:返回Set实例的成员总数

Set 实例的方法分为两大类:操作方法(用于操作数据)和遍历方法(用于遍历成员)。下面先介绍四个操作方法。

  • add(value):添加某个值,返回Set结构本身。

  • delete(value):删除某个值,返回一个布尔值,表示删除是否成功。

  • has(value):返回一个布尔值,表示该值是否为Set的成员。

  • clear():清除所有成员,没有返回值。

*去除数值重复元素的方法

// 去除数组的重复成员
[...new Set(array)]

*Array.from方法可以将 Set 结构转为数组。

const items = new Set([1, 2, 3, 4, 5]);
const array = Array.from(items);

遍历操作

Set 结构的实例有四个遍历方法,可以用于遍历成员。

  • keys():返回键名的遍历器

  • values():返回键值的遍历器

  • entries():返回键值对的遍历器

  • forEach():使用回调函数遍历每个成员

Set的遍历顺序就是插入顺序。这个特性有时非常有用,比如使用Set保存一个回调函数列表,调用时就能保证按照添加顺序调用。
keys方法、values方法、entries方法返回的都是遍历器对象。由于 Set 结构没有键名,只有键值(或者说键名和键值是同一个值),所以keys方法和values方法的行为完全一致。

let set = new Set(['red', 'green', 'blue']);for (let item of set.keys()) {console.log(item);
}
// red
// green
// bluefor (let item of set.values()) {console.log(item);
}
// red
// green
// bluefor (let item of set.entries()) {console.log(item);
}
// ["red", "red"]
// ["green", "green"]
// ["blue", "blue"]

Set结构的实例的forEach方法,用于对每个成员执行某种操作,没有返回值。

 let set = new Set([1, 2, 3]);
set.forEach((value, key) => console.log(value * 2) )
// 2
// 4
// 6

实现并集(Union)、交集(Intersect)和差集(Difference)

let a = new Set([1, 2, 3]);
let b = new Set([4, 3, 2]);// 并集
let union = new Set([...a, ...b]);
// Set {1, 2, 3, 4}// 交集
let intersect = new Set([...a].filter(x => b.has(x)));
// set {2, 3}// 差集
let difference = new Set([...a].filter(x => !b.has(x)));
// Set {1}

WeakSet

WeakSet 结构与 Set 类似,也是不重复的值的集合。但是,它与 Set 有两个区别。

首先,WeakSet 的成员只能是对象,而不能是其他类型的值。

const ws = new WeakSet();
ws.add(1)
// TypeError: Invalid value used in weak set
ws.add(Symbol())
// TypeError: invalid value used in weak set

上面代码试图向 WeakSet 添加一个数值和Symbol值,结果报错,因为 WeakSet 只能放置对象。

其次,WeakSet 中的对象都是弱引用,即垃圾回收机制不考虑 WeakSet 对该对象的引用,也就是说,如果其他对象都不再引用该对象,那么垃圾回收机制会自动回收该对象所占用的内存,不考虑该对象还存在于 WeakSet 之中。

这是因为垃圾回收机制依赖引用计数,如果一个值的引用次数不为0,垃圾回收机制就不会释放这块内存。结束使用该值之后,有时会忘记取消引用,导致内存无法释放,进而可能会引发内存泄漏。WeakSet 里面的引用,都不计入垃圾回收机制,所以就不存在这个问题。因此,WeakSet 适合临时存放一组对象,以及存放跟对象绑定的信息。只要这些对象在外部消失,它在 WeakSet 里面的引用就会自动消失。

由于上面这个特点,WeakSet 的成员是不适合引用的,因为它会随时消失。另外,由于 WeakSet 内部有多少个成员,取决于垃圾回收机制有没有运行,运行前后很可能成员个数是不一样的,而垃圾回收机制何时运行是不可预测的,因此 ES6 规定 WeakSet 不可遍历。

WeakSet的应用

WeakSet 结构有以下三个方法。

  • WeakSet.prototype.add(value):向 WeakSet 实例添加一个新成员。

  • WeakSet.prototype.delete(value):清除 WeakSet 实例的指定成员。

  • WeakSet.prototype.has(value):返回一个布尔值,表示某个值是否在WeakSet 实例之中。

 const ws = new WeakSet();const obj = {};const foo = {};ws.add(window);ws.add(obj);ws.has(window); // truews.has(foo);    // falsews.delete(window);ws.has(window);    // false

WeakSet没有size属性,没有办法遍历它的成员。

    ws.size // undefinedws.forEach // undefinedws.forEach(function(item){ console.log('WeakSet has ' + item)})// TypeError: undefined is not a function

上面代码试图获取size和forEach属性,结果都不能成功。

WeakSet 不能遍历,是因为成员都是弱引用,随时可能消失,遍历机制无法保证成员的存在,很可能刚刚遍历结束,成员就取不到了。WeakSet 的一个用处,是储存 DOM 节点,而不用担心这些节点从文档移除时,会引发内存泄漏。

参考:

  1. Learning Javascript Data Structures and Algorithms

  2. Set和Map数据结构

推荐一个找vue,angular组件的轮子工厂

前端面试总结--数据结构与算法一
前端面试总结--数据结构与算法二
前端面试总结--数据结构与算法三
前端面试总结--数据结构与算法四

前端面试总结--数据结构与算法五相关推荐

  1. GitHub 上值得前端学习的数据结构与算法项目

    Hello,大家好,我是你们的 前端章鱼猫. 简介 前端章鱼猫从 2016 年加入 GitHub,到现在的 2020 年,快整整 5 个年头了. 相信很多人都没有逛 GitHub 的习惯,因此总会有开 ...

  2. 妥妥的去面试之数据结构与算法(一)

    笔者由于在找工作,所以近期最主要的任务就是准备面试,不打无准备之仗.只有你准备充分了,那么你想要的机会才有机会入你怀中. 笔者会将准备面试的学习过程记录下来,方便自己复盘的同时也希望能给一道找工作的小 ...

  3. 数据结构与算法五:哈希表-哈希函数设计原则-哈希冲突解决方案

    一.哈希表的定义: 二.哈希表举例: 哈希函数就是映射关系 三.哈希表应用举例: Leetcode上第387题: 思路:通过s.charAt(i)-'a'将字符串中的字符映射成hash表,出现一次,在 ...

  4. 前端如何准备数据结构和算法

    一.导读 据我了解,前端程序员有相当一部分对"数据结构"和"算法"的基础概念都不是很清晰,这直接导致很多人在看到有关这部分的内容就会望而却步. 实际上,当你了解 ...

  5. 前端面试中常见的算法问题

    虽说我们很多时候前端很少有机会接触到算法.大多都交互性的操作,然而从各大公司面试来看,算法依旧是考察的一方面.实际上学习数据结构与算法对于工程师去理解和分析问题都是有帮助的.如果将来当我们面对较为复杂 ...

  6. 手撕前端面试之经典排序算法

    作者 | 霍语佳       责编 | 欧阳姝黎 排序算法是面试中的高频考察点,我们需要熟练掌握.本文整理了最经典.最常用的排序算法并且搭配了动图和视频,希望能够帮助你更加轻松的理解它们. 首先,根据 ...

  7. Android版数据结构与算法(五):LinkedHashMap核心源码彻底分析

    版权声明:本文出自汪磊的博客,未经作者允许禁止转载. 上一篇基于哈希表实现HashMap核心源码彻底分析 分析了HashMap的源码,主要分析了扩容机制,如果感兴趣的可以去看看,扩容机制那几行最难懂的 ...

  8. 保研/面试复习-数据结构与算法-万字总结(近三万字)

    以下是笔者整理的保研/面试容易被问到的算法问题,包含最短路径,dfs,bfs,最小生成树MST(krusal和prim),KMP(这个可能较难,如果算法不是问得很深,一般不会问到),十种排序算法(大部 ...

  9. Python数据结构与算法(五)--链表

    链表 链表的定义: 链表(Linked list)是一种常见的基础数据结构,是一种线性表,但是不像顺序表一样连续存储数据,而是在每一个节点(数据存储单元)里存放下一个节点的位置信息(即地址). 单项链 ...

  10. 年后跳槽BAT必看:10种数据结构、算法和编程课助你面试通关

    作者 | javinpaul 译者 | 大鱼 编辑 | 一一 出品 | AI 科技大本营 进入 BAT 这样的巨头企业工作,无疑是很多程序员的梦想.但事实上,能通过这些公司高难度编程面试的只是一小撮人 ...

最新文章

  1. php遍历文件夹下文件内容_PHP遍历某文件夹下的文件与文件夹名
  2. 并发编程 - 协程 - 1.协程概念/2.greenlet模块/3.gevent模块/4.gevent实现并发的套接字通信...
  3. docker容器数据卷基本操作
  4. 最新版MySQL操作---语句规范
  5. 未来计算机作文700字,未来的科技作文700字
  6. [书籍推荐]为了自己的钱包,为了自己的时间——分享一下自己的淘书经验
  7. 卸载oracle 10g
  8. java手机翻译,使用JUniversal翻译Android项目
  9. iPhone5捣鼓mobile terminal
  10. 浅谈微信小程序开发工具
  11. 网口压线顺序_网线水晶头接法
  12. TEM测试常见问题及解答(二)
  13. kind安装k8s集群
  14. 第三方支付API支付宝支付申请流程 支付宝新老版本
  15. 爱加密加固病毒分析-脱壳篇
  16. 三维重建入门学习————建模软件Blender入门篇
  17. 三相SVPWM逆变器MATLAB仿真实验,三相SVPWM逆变电路MATLAB仿真
  18. Firewall 防火墙常用命令
  19. BlueTooth: 浅析CC2540的OSAL原理
  20. 【年终总结】我的前端之行,回顾2022,展望2023

热门文章

  1. python assert简单记忆方法
  2. Ubuntu18如何阻止自动切换程序多个窗口的顺序
  3. php实现微信登录详细教程,[文档教程]PHP实现微信开放平台扫码登录源码下载 - 技术编程 - 极思维...
  4. go导出mysql中的excel表,MySQL导出数据,并转存到Excel表格中
  5. beta分布_浅谈分布之分布(beta分布)贝叶斯分析之1 精选
  6. 【云安全课程】云平台使用安全
  7. [Linux] RIO C++封装
  8. springMVC之applicationcontext.xml配置说明
  9. 【工具类】Android判断SD卡状态
  10. ADO.NET入门教程(六) 谈谈Command对象与数据检索