说到集合, 第一个想到的就是中学学到的那个数学概念: 集合 https://baike.baidu.com/item/集合/2908117?fr=aladdin . 在我们开始集合相关的 js 实现前, 我们有必要来了解一下什么是集合以及集合的数学概念.
好吧, 我们一起来复习一下早就被我们遗忘的集合.
集合是由一组无序且唯一的项组成的. 集合这个数据结构使用了与有限集合 https://baike.baidu.com/item/有限集合/9275995?fr=aladdin 相同的数学概念. 在数学中, 集合是指具有某种特定性质的具体的或抽象的对象汇总成的集体, 这些对象称为该集合的元素.
比如, 一个包括 0 到 9 十个数字的集合表示为: N = {0,1,2,3,4,5,6,7,8,9}. 集合中的对象列表用 {}(大括号) 包围. 还有一个概念叫做空集, 也就是该集合中不包含任何元素, 也就是{}, 空集是任何集合的子集.
除了集合的基本概念, 还有一些简单的集合操作, 比如并集, 交集, 差集和子集等. 在后面会详细的介绍这些集合的操作.
那么集合的数据概念就简单介绍完了. 我们看看如何去创建一个集合类(set).
- function Set() {
- let items = {};
- }
嗯, 这就是 set 的骨架, 哎?? 我记得好像 ES6 中就有 http://es6.ruanyifeng.com/#docs/set-map#Set 这个东东啊? 嗯... 是的, 我们会在后面 (下一篇) 简单介绍下 ES6 原生的 set 类.
这里我们使用对象而不是数组来表示集合. 其实用数组也是可以的. 那么是不是说, 前面学过的栈和队列也都可以用对象来实现? 是的, 不要怀疑可行性. 因为其实我们在改进这两个数据结构的时候用的就是 weapMap 这种 ES6 新增的结构.
那么接下来要说一下 set 类有哪些可用的方法.
1,add(value): 向集合中添加一个新的项.
2,delete(value): 从集合移除一个值.
3,has(value): 如果值在集合中, 返回 true, 否则返回 false.
4,clear(): 清空集合中的所有元素.
5,size(): 返回集合所包含元素的数量.
6,values(): 返回一个包含集合中所有值的数组.
- function Set() {
- let items = {};
- // 判断该 set 实例中是否存在该 value
- this.has = function (value) {
- // 检查它 (或其原型链) 上是否包含具有指定名称的属性的对象. 但是 in 运算符会查找其原型链上的属性. 所以我们用下面的方法更好
- //return value in items;
- //hasOwnProperty 方法可以用来检测一个对象是否含有特定的自身属性; 和 in 运算符不同, 该方法会忽略掉那些从原型链上继承到的属性.
- // 所以我们也可以用 hasOwnProperty 来判断一个对象的自身属性是否存在
- return items.hasOwnProperty(value);
- }
- this.add = function (value) {
- // 通过我们上面写的 has 方法来判断这个值是否存在, 如果不存在就添加进去, 存在就返回 false
- if(!this.has(value)) {
- items[value] = value;
- return true;
- }
- return false;
- }
- // 同样的道理, 判断该 set 中是否有要删除的对象, 如果有就删除, 没有就返回 false
- this.remove = function (value) {
- if(this.has(value)) {
- delete items[value];
- return true;
- }
- return false;
- }
- // 直接充值 items 为空, 就变相的清空了 items 中的所有属性
- this.clear = function() {
- items = {};
- }
- //Object.keys 是 ES6 中为对象新增的原生方法, 它会返回一个数组, 其中包含对象的所有元素, 这样我们就可以获取其元素的个数了.
- this.size = function () {
- return Object.keys(items).length;
- }
- // 上面我们用 ES6 新方法来获取 items 的长度, 但是或许有些浏览器的兼容性不是很好. 所以我们也可以用循环遍历计数的方式来完成这个功能
- this.sizeLegacy = function () {
- let count = 0;
- for(let key in items) {
- if(items.hasOwnProperty(key))
- ++count;
- }
- return count;
- }
- this.values = function () {
- let values = [];
- for(let i = 0,keys = Object.keys(items);i < keys.length; i++) {
- values.push(items[keys[i]]);
- }
- return values;
- }
- this.valuesLegacy = function () {
- let values = [];
- for(let key in items) {
- if(items.hasOwnProperty(key)) {
- values.push(items[key])
- }
- }
- return values;
- }
- }
- var set = new Set();
- set.add(1);
- console.log(set.values());//[1]
- set.add(2);
- console.log(set.values());//[1, 2]
- console.log(set.size());//2
- set.remove(2);
- console.log(set.values());//[1]
这样我们就完整的实现了我们自定义的 set 类, 发没发现我的注释越来越少了, 越到后面的学习也就越简单了. 因为其实很多东西都是类似的, 有它共同的 point.
好了, 集合的实现我们已经完成了. 下一篇文章会介绍一下集合的几种操作方法以及 ES6 原生 set 的一些简单用法介绍.
最后, 由于本人水平有限, 能力与大神仍相差甚远, 若有错误或不明之处, 还望大家不吝赐教指正. 非常感谢!
来源: https://www.cnblogs.com/zaking/p/8902219.html