目录
一、集合【Set】
1.集合的特点
集合比较常见的实现方式是哈希表,这里使用JavaScript的Object类进行封装。
集合通常是由一组无序的、不能重复的元素构成。
- 数学中常指的集合中的元素是可以重复的,但是计算机中集合的元素不能重复。
2.集合是特殊的数组
- 特殊之处在于里面的元素没有顺序,也不能重复。
- 没有顺序意味着不能通过下标值进行访问,不能重复意味着相同的对象在集合中只会存在一份。
3.实现集合类
在ES6中的Set类就是一个集合类,这里我们重新封装一个Set类,了解集合的底层实现。
JavaScript中的Object类中的key就是一个集合,可以使用它来封装集合类Set。
<script>
//封装集合类
function Set(){
// 属性
// 这里不设置为数组,是因为数组中的元素可以重复
// JavaScript中的Object类中的key就是一个集合,可以使用它来封装集合类Set
this.items={}
// 方法
}
</script>
4.集合的操作
代码实现
<script>
//封装集合类
function Set() {
// 属性
// 这里不设置为数组,是因为数组中的元素可以重复
// JavaScript中的Object类中的key就是一个集合,可以使用它来封装集合类Set
this.items = {}
// 方法
// add方法:添加元素
Set.prototype.add = function (value) {
// 判断当前集合中是否已经包含该元素
if (this.has(value)) {
return false
}
// 将元素添加到集合中
// 此时key=value value=value
this.items[value] = value
return true
}
// has方法:判断集合中是否包含value值
Set.prototype.has = function (value) {
return this.items.hasOwnProperty(value)
}
// remove方法:删除元素
// 不能传入下标值,因为集合中没有下标这个概念
Set.prototype.remove = function (value) {
// 1.判断该集合中是否包含该元素
if (!this.has(value)) {
return false
}
// 2.将元素从属性中删除
delete this.items[value]
return true
}
// clear方法
Set.prototype.clear = function () {
this.items = {}
}
// size方法
Set.prototype.size = function () {
return Object.keys(this.items).length
}
//获取集合中所有的值
//六.values方法
Set.prototype.values = function () {
return Object.keys(this.items)
}
}
</script>
测试代码
//测试集合类
//1.创建Set类对象
let set = new Set()
//添加元素
//2.测试add方法
console.log(set.add('a')); //67
console.log(set.add('a')); //68
console.log(set.add('b')); //69
console.log(set.add('c')); //70
console.log(set.add('d')); //71
//3.测试values方法
console.log(set.values()); //74
//删除元素
//4.测试remove方法
console.log(set.remove('a')); //78
console.log(set.remove('a')); //79
console.log(set.values()); //80
//5.测试has方法
console.log(set.has('b')); //83
//6.测试size方法和clear方法
console.log(set.size()); //86
set.clear()
// 由于clear方法的实现原理为指向另外一个空对象,所以不影响原来的对象
console.log(set.size()); //89
console.log(set.values());
5.集合间的操作
- 并集:对于给定的两个集合,返回一个包含两个集合中所有元素的新集合;
- 交集:对于给定的两个集合,返回一个包含两个集合中共有元素的新集合;
- 差集:对于给定的两个集合,返回一个包含所有存在于第一个集合且不存在于第二个集合的元素的新集合;
- 子集:验证一个给定集合是否是另一个集合的子集;
6.求并集操作
实现思路
创建集合C代表集合A和集合B的并集,先将集合
A
中的所有元素添加到集合C
中,再遍历集合B
,如果是集合C
所没有的元素就把它添加到集合C
中。
代码实现
// 并集
Set.prototype.union=function(otherSet){
// this:集合对象A
// otherSet:集合对象B
// 1.创建新的集合
var unionSet=new Set()
// 2.将A集合中所有的元素添加到新集合中
var values=this.values() //调用上面获取元素的方法
for(var i=0;i<values.length;i++){
unionSet.add(values[i])
}
// 3.取出B集合中的元素,判断是否需要添加到新集合
values=otherSet.values()
for(var i=0;i<values.length;i++){
unionSet.add(values[i])
}
return unionSet
}
测试代码
// 1.创建两个集合,并且添加元素
var setA=new Set()
setA.add('abc')
setA.add('cba')
setA.add('sdf')
var setB=new Set()
setB.add('aaa')
setB.add('abc')
setB.add('ccc')
// 2.求两个集合的并集
unionSet=setA.union(setB)
alert(unionSet.values())
7.求交集操作
实现思路
遍历集合A,当取得的元素也存在于集合B时,就把该元素添加到另一个集合C中。
代码实现
// 交集
Set.prototype.intersection =function(otherSet) {
// this:集合A
// otherSet:集合B
//1.创建新的集合
let intersectionSet = new Set()
//2.从A中取出一个元素,判断是否同时存在于集合B中,是则放入新集合中
let values = this.values()
for (let i = 0; i < values.length; i++) {
let item = values[i]
// 判断集合B中是否也包含该元素
if (otherSet.has(item)) {
intersectionSet.add(item)
}
}
return intersectionSet
}
}
测试代码
//测试交集操作
// 1.创建两个集合,并且添加元素
var setA = new Set()
setA.add('abc')
setA.add('cba')
setA.add('sdf')
var setB = new Set()
setB.add('aaa')
setB.add('abc')
setB.add('ccc')
// 2.求两个集合的交集
intersectionSet = setA.intersection(setB)
alert(intersectionSet.values())
8.求差集操作
实现思路
遍历集合A,当取得的元素不存在于集合B时,就把该元素添加到另一个集合C中。
代码实现
// 差集
Set.prototype.diffrence = otherSet => {
//this:集合A
//otherSet:集合B
//1.创建新的集合
var diffrenceSet = new Set()
//2.取出A集合中的每一个元素,判断是否同时存在于B中,不存在则添加到新集合中
var values = this.values()
for (var i = 0; i < values.length; i++) {
var item = values[i]
// 是取反操作
if (!otherSet.has(item)) {
diffrenceSet.add(item)
}
}
return diffrenceSet
}
代码测试
//测试差集操作
// 1.创建两个集合,并且添加元素
var setA = new Set()
setA.add('abc')
setA.add('cba')
setA.add('sdf')
var setB = new Set()
setB.add('aaa')
setB.add('abc')
setB.add('ccc')
// 2.求两个集合的交集
diffrenceSet = setA.diffrence(setB)
alert(diffrenceSet.values())
9.求子集操作
实现思路
遍历集合A,当取得的元素中有一个不存在于集合B时,就说明集合A不是集合B的子集,返回false。
代码实现
// 子集
Set.prototype.subset = otherSet => {
//this:集合A
//otherSet:集合B
//遍历集合A中的所有元素,如果发现,集合A中的元素,在集合B中不存在,那么放回false,如果遍历完整个集合A没有返回false,就返回true
let values = this.values()
for (let i = 0; i < values.length; i++) {
let item = values[i]
if (!otherSet.has(item)) {
return false
}
}
return true
}
代码测试
//测试子集操作
// 1.创建两个集合,并且添加元素
var setA = new Set()
setA.add('abc')
setA.add('cba')
setA.add('sdf')
var setB = new Set()
setB.add('aaa')
setB.add('abc')
setB.add('ccc')
// 5.判断子集
alert(setA.subset(setB))
二、字典【Map】
1.认识字典
2.字典特点:通过键值对进行保存的
字典中key是不能重复且无序的,而Value可以重复
3.字典和映射的关系
- 有些编程语言中称这种映射关系为字典,如Swift中的Dictonary,Python中的dict;
- 有些编程语言中称这种映射关系为Map,比如Java中的HashMap&TreeMap等;
4.字典和数组
- 字典和数组对比的话,字典可以非常方便的通过key来搜索对应的value, key可以包含特殊含义,也更容易被人们记住
5.字典和对象
- 很多编程语言(比如Jav)中对字典和对象区分比较明显,对象通常是一种在编译期就确定下来的结构,不可以动态的添加或者删除属性.而字典通常会使用类似于哈希表的数据结构去实现一种可以动态的添加数据的结构
- 但是在JavaScript中,似乎对象本身就是一种字典.所有在早期的JavaScript中,没有字典这种数据类型,因为你完全可以使用对象去代替.