这是我参与11月更文挑战的第16天,活动详情查看:2021最后一次更文挑战
介绍
我们在数学概念中,集合是一组不同对象的集,而且在ES 2015中Set类已经是JavaScript API的一部分了。本期我们将用普通对象来模拟实现一个这样的类,虽然非常简单,但也是一个重要的数据结构,我们就通过这个模拟实现来加深对其的认识吧。
概念
集合是由一组无序且唯一(即不能重复)的项组成的。该数据结构使用了与有限集合相同的数学概念,但应用在计算机科学的数据结构中。
正文
1.基本结构
class MySet{
constructor(){
this.items = {};
this.size = 0;
}
has(item){}
add(item){}
delete(item){}
clear(){}
values(){}
}
export default MySet;
我们用items来做对象存储,用size来记录当前集合内元素的数量。
- has:判断传入元素是否存在,返回一个布尔类型。
- add:推送一个元素进入集合内,返回当前集合。
- delete:删除一个集合内的元素,返回一个布尔类型。
- clear:清空当前集合。
- values:返回集合内元素的值。
2.has方法
has(item){
return Object.prototype.hasOwnProperty.call(this.items,item)
}
Object.prototype.hasOwnProperty来判断当前存储器中是否存在某个元素。当然你可以可以使用items in item来判断。但是hasOwnProperty更加准确因为,in方法会判断当前对象原型链上是否有属性匹配,而hasOwnProperty则只会判断当前对象是否有属性匹配。
还有同学会想为什么用call呢,直接items.hasOwnProperty(item)不行么,其实是可以的,但是最好用Object.prototype.hasOwnProperty去调用,因为items是一个自定义对象,而自定义对象有可能原型链会移除或者改变,这样自定义的对象就可能没有hasOwnProperty方法,在一些检查工具中就会显示错误。
3.add方法
add(item) {
if (!this.has(item)) {
this.items[item] = item;
this.size = Object.keys(this.items).length;
}
return this;
}
推一个元素进入集合中,要判断是否集合内存在,因为刚刚也说了集合是一组不同对象的集,所以我们要用has方法先判断一下是否已经存在,如果存在那么就存储起来,然后用Object.keys的长度重置一下当前集合的数量。返回集合本身,这样我们还可以进行链式的调用了,即myset.add(1).add(2).add(3)。
4.delete方法
delete(item) {
if (!this.has(item)) return false;
delete this.items[item];
this.size = Object.keys(this.items).length;
return true;
}
删除非常简单判断一下是否存在,如果不存在返回false证明删除失败,成功则返回true,当然别忘了要更新一下当前集合数量。
5.clear方法
clear() {
this.items = {}
this.size = 0;
}
清空很简单就是把集合重置一下,这里为了方便用了重新指向新内存地址,你可以可以变量删除其内容,这里不做赘述。
6.values方法
values() {
let values = [];
for (const key in this.items) {
if (this.items.hasOwnProperty(key)) {
values.push(key)
}
}
return values;
}
获取当前集合各个元素的值我们用了for..in方法,遍历后的值塞入数组后将数组返回,当然你可以使用Object.values方法可以直接返回数组。但缺点是Object.values是ES 2017的API,兼容状况会不如for..in。
7.使用
import MySet from "./js/MySet"
const myset= new MySet();
myset.has(1) // false
myset.add(1).add(1).add(2).add(3)
myset.has(1) // true
myset.delete(2) // true
myset.values() // [1,3]
myset.clear()
myset.size // 0
我们可以看到,has可以判断元素是否存在于该集合,链式推送元素,也可以删除元素,以及返回当前元素数据等方法,我们均已完成了模拟实现。
结语
集合看似是一个非常简单的数据结构,但是我们在我们开发实践中意义重大。比如,集合常被用于查询的设计和处理,它可是数据库是大多数应用程序的根基。我们通过学习模拟是希望大家对数据结构加深理解,工作中合理使用,使我们的设计的数据更清晰有序,更便于维护。