三、集合与字典

三、集合与字典

3.1 集合结构

3.1.1 集合简介

集合比较常见的实现方式是哈希表,这里使用JavaScript的Object类进行封装。
集合通常是由一组无序的、不能重复的元素构成。
数学中常指的集合中的元素是可以重复的,但是计算机中集合的元素不能重复

集合是特殊的数组
  • 特殊之处在于里面的元素没有顺序,也不能重复
  • 没有顺序意味着不能通过下标值进行访问,不能重复意味着相同的对象在集合中只会存在一份
实现集合类
  • 在ES6中的Set类就是一个集合类,这里我们重新封装一个Set类,了解集合的底层实现。
  • JavaScript中的Object类中的key就是一个集合,可以使用它来封装集合类Set
集合常见的操作
  • add(value):向集合添加一个新的项;
  • remove(value):从集合中移除一个值;
  • has(value):如果值在集合中,返回true,否则返回false;
  • clear():移除集合中的所有项;
  • size():返回集合所包含元素的数量,与数组的length属性相似;
  • values():返回一个包含集合中所有值的数组;

3.1.2 代码实现

代码实现
function Set() {
  //属性
  this.items = {}
  //has(value):如果值在集合中,返回true,否则返回false;
  Set.prototype.has = (value) => {
    return this.items.hasOwnProperty(value)
  }
  //add(value):向集合添加一个新的项;
  Set.prototype.add = (value) => {
    if (this.has(value)) return false
    this.items[value] = value
    return true
  }
  //remove(value):从集合中移除一个值;
  Set.prototype.remove = (value) => {
    if (!this.has(value)) return false
    delete this.items[value]
    return true
  }
  //clear():移除集合中的所有项;
  Set.prototype.clear = () => {
    this.items = {}
  }
  //size():返回集合所包含元素的数量,与数组的length属性相似;
  Set.prototype.size = () => {
    return Object.keys(this.items).length
  }
  //values():返回一个包含集合中所有值的数组;
  Set.prototype.values = () => {
    return Object.keys(this.items)
  }
}
测试代码
//测试集合类
//1.创建Set类对象
let set = new Set()
//添加元素
//2.测试add方法
console.log(set.add('a'));
console.log(set.add('a'));
console.log(set.add('b'));
console.log(set.add('c'));
console.log(set.add('d'));
//3.测试values方法
console.log('set.values()',set.values());
//删除元素
//4.测试remove方法
console.log('set.remove(a)',set.remove('a'));
console.log('set.remove(a)',set.remove('a'));
console.log('set.values()',set.values());
//5.测试has方法
console.log('set.has(b)',set.has('b'));
//6.测试size方法和clear方法
console.log('set.size()',set.size());
set.clear()
// 由于clear方法的实现原理为指向另外一个空对象,所以不影响原来的对象
console.log('set.size()',set.size());
console.log('set.values()',set.values());
测试结果

![image.png](https://img-blog.csdnimg.cn/img_convert/bbafd7fd2df4fe4971b5974d2fbfcf92.png#clientId=ufed64531-909e-4&crop=0&crop=0&crop=1&crop=1&from=paste&height=381&id=u1c8393d0&margin=[object Object]&name=image.png&originHeight=447&originWidth=501&originalType=binary&ratio=1&rotation=0&showTitle=false&size=19048&status=done&style=none&taskId=ua8233840-02ab-4202-b48f-24479e57a82&title=&width=427.5)

3.1.3 集合间操作

集合间操作
  • 并集:对于给定的两个集合,返回一个包含两个集合中所有元素的新集合
  • 交集:对于给定的两个集合,返回一个包含两个集合中共有元素的新集合
  • 差集:对于给定的两个集合,返回一个包含所有存在于第一个集合,且不存在于第二个集合的元素的新集合
  • 子集:验证一个给定集合,是否是另一个集合的子集
并集的实现

实现思路:创建集合C,代表集合A和集合B的并集,先将集合A中的所有元素添加到集合C中,再遍历集合B,如果是集合C所没有的元素,就把它添加到集合C中。

 Set.prototype.union = otherSet => {
   // this:集合对象A
   // otherSet:集合对象B
   //1.创建一个新的集合
   let unionSet = new Set()

   //2.将A集合中的所有元素添加到新集合中
   let values = this.values()
   // for(let i of values){
   //   unionSet.add(i)
   // }
   for(let i = 0;i < values.length;i++){
     unionSet.add(values[i])
   }

   //3.取出B集合中的元素,判断是否需要加到新集合中
   values = otherSet.values()
   // for(let i of values){
   //   //由于集合的add方法已经对重复的元素进行了判断,所以这里可以直接添加
   //   unionSet.add(i)
   // }
   for(let i = 0;i < values.length;i++){
     unionSet.add(values[i])
   }
   return unionSet
 }
交集的实现

实现思路: 遍历集合A,当取得的元素也存在于集合B时,就把该元素添加到另一个集合C中。

 Set.prototype.intersection = 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]
     if (otherSet.has(item)) {
       intersectionSet.add(item)
     }
   }
   return intersectionSet
 }
差集的实现

实现思路: 遍历集合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
}
子集的实现

实现思路: 遍历集合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
 }

3.2 字典结构

3.2.1 字典简介

字典的特点
  • 字典存储的是键值对,主要特点是一一对应
  • 比如保存一个的信息,数组形式:[20,‘nino’,‘male’],可通过下标值取出信息;字典形式:{“age”:20,“name”:“nino”,“sex”:“male”},可以通过key取出value
  • 此外,在字典中,key是不能重复且无序的,而value可以重复
字典和映射的关系

有些编程语言中称这种映射关系为字典,如Swift中的Dictionary,Python中的dict
有些编程语言中称这种映射关系为Map,如Java中的HashMap,TreeMap等

字典类常见的操作
  • set(key,value):向字典中添加新元素。
  • remove(key):通过使用键值来从字典中移除键值对应的数据值。
  • has(key):如果某个键值存在于这个字典中,则返回true,反之则返回false。
  • get(key):通过键值查找特定的数值并返回。
  • clear():将这个字典中的所有元素全部删除。
  • size():返回字典所包含元素的数量。与数组的length属性类似。
  • keys():将字典所包含的所有键名以数组形式返回。
  • values():将字典所包含的所有数值以数组形式返回。

3.2.2 字典结构的封装

字典类可以基于JavaScript中的对象结构来实现,比较简单,这里直接实现字典类中的常用方法


function Dictionary(params) {
  //字典属性
  this.items = {}
  //set(key,value):向字典中添加新元素。
  Dictionary.prototype.set = (key, value) => {
    this.items[key] = value
  }
  //has(key):如果某个键值存在于这个字典中,则返回true,反之则返回false。
  Dictionary.prototype.remove = (key) => {
    return this.items.hasOwnProperty(key)
  }
  //remove(key):通过使用键值来从字典中移除键值对应的数据值。
  Dictionary.prototype.remove = (key) => {
    if (!this.has(key)) return false
    delete this.items[key]
    return true
  }
  //get(key):通过键值查找特定的数值并返回。
  Dictionary.prototype.get = key => {
    return this.has(key) ? this.items[key] : undefined
  }
  //clear():将这个字典中的所有元素全部删除。
  Dictionary.prototype.clear = () => {
    this.items = {}
  }
  //size():返回字典所包含元素的数量。与数组的length属性类似。
  return this.keys().length
  //keys():将字典所包含的所有键名以数组形式返回。
  Dictionary.prototype.keys = () => {
    return Object.keys(this.items)
  }
}
  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 打赏
    打赏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

呐呐呐呐。

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值