JavaScript 数据结构之集合创建(2)

目录
  • 前言
  • 一、集合运算
    • 1.并集
    • 2.交集
    • 3.差集
    • 4.子集
  • 二、使用集合运算
  • 三、总结

前言

上一篇JavaScript 数据结构 之集合创建(1)我们介绍了什么是集合,并且手动实现了一个集合的类。简单总结,集合就是一组元素唯一,并且没有顺序的数据集,关键是元素唯一。

ES6 提供了原生的集合支持,就是新增的 Set 数据类型。其实在上篇我们几乎已经实现了 Set 的所有功能,如果还不了解集合,请看上篇内容

但是我们也说到,Set 的基本功能中不包含数学运算如 交集,并集,差集,事实上这也是集合的一部分。本篇我们就要介绍这类集合的运算。

一、集合运算

集合在计算机世界中主要的应用之一就是数据库。比如在一个关系型数据库当中,我们常用的查询,基本都是对一个或多个数据集合进行筛选,合并,过滤等运算。

比如你写一条 SQL 语句,它可能是要获取表中的所有数据,也可能是根据条件获取一部分数据,还有可能是关联查询,要一次性获取多个表的数据。

根据不同的需求来决定集合如何处理,这在 SQL 中叫做联接。SQL 联接的基础就是集合运算。

我们对集合的元算包含如下几个:

  • 并集:给定两个集合,返回包含两个集合中所有元素的新集合
  • 交集:给定两个集合,返回包含共有元素的新集合
  • 差集:给定两个集合,返回第一个集合有,第二个集合没有的元素的新集合
  • 子集:验证一个集合是否是另一个集合的子集(一部分)

我们看相应的如何实现。

1.并集

并集说白了就是包含两个集合的所有元素但是不重复的集合。

其实也很好理解,我们在 Set 类的基础上实现一个 union 方法。

union(otherSet) {
  let unionSet = new Set()
  this.values().forEach(value=> unionSet.add(value))
  otherSet.values().forEach(value=> unionSet.add(value))
  return unionSet;
}

如上的实现方式,首先实例化一个新集合,然后分别将两个集合的全部元素加入到新集合。因为集合在添加元素时会做重复校验,所以全部添加后新集合包含了所有元素,且不重复。

2.交集

交集就是两个集合共有的元素组成的一个新集合,这个集合肯定是两个集合的子集。

我们来实现 intersection 方法:

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

这个实现方式和并集一样,首先定义新的集合。只不过是在一个集合元素的遍历中,判断元素是否在另一个集合中,如果在则添加到新集合,这样新集合就是一个交集。

改进交集

功能实现了,我们再看另外一种情况。假设两个集合如下:

  • 集合 A:[1, 2, 3, 4, 5, 6, 7]
  • 集合 B:[4, 7]

如果按照上面的方式,我们需要循环七次,才能得到交集。那有没有办法选择长度更小的集合循环,并实现功能呢?

有啊,假设遍历集合 B,只需要循环两次。我们看如何改进:

intersection(otherSet) {
  let inters = new Set();
  let bigvals = this.values()
  let lessvals = otherSet.values();
  if(bigvals.length < lessvals.length) {
    bigvals = otherSet.values();
    lessvals =  this.values()
  }
  for(let i = 0; i < lessvals.length; i++) {
    if(bigvals.includes(lessvals[i])) {
      inters.add(lessvals[i])
    }
  }
  return inters;
}

这种方式是先判断哪个集合的长度更短,然后遍历更短的那个集合,再判断元素是否在另一个集合里,这样就避免了多余的循环。

3.差集

差集是指元素存在于集合 A 中,但不存在于集合 B 中,也就是计算 A - B 的部分。

我们来实现 Set 类的 different 方法:

different(otherSet) {
  let diffSet = new Set();
  this.values().forEach(value=> {
    if(!otherSet.has(value)) {
      diffSet.add(value)
    }
  })
  return diffSet;
}

从代码中能看出来,差集与交集的实现逻辑正好相反。

4.子集

在数学概念中,如果集合 A 包含于集合 B,也就是说集合 A 中所有的元素集合 B 中都存在,那我们认为集合 A 是集合 B 的子集。

从程序的角度来看,集合 A 是从集合 B 中过滤出来的一部分,那么集合 A 就是一个子集。

我们来实现子集的 isSubsetOf 方法:

isSubsetOf(otherSet) {
  let isSubset = true
  let values = otherSet.values()
  for(let i = 0; i < values.length; i++) {
    if(!this.has(values[i])) {
      isSubset = false; break;
    }
  }
  return isSubset;
}

这个方法是检测参数集合中,是否每个元素都在实例集合中存在。如果有一个不存在,则表示参数集合不是子集,终止循环并返回结果。

其实还有更简单的方法:

isSubsetOf(otherSet) {
  return otherSet.values().every(value=> this.has(value))
}

every 方法可以判断是否每个元素是否都符合条件。如果符合就返回 true,否则返回 false

二、使用集合运算

上面完成了集合基本运算的实现,现在我们来使用一下吧:

let setA = new Set()
setA.add('北京')
setA.add('上海')
setA.add('广州')

let setB = new Set()
setB.add('北京')
setB.add('南京')
setB.add('武汉')

首先添加了两个集合,然后用它们来测试基本元算:

let sets = setA.union(setB);
console.log(sets.values()); // ['北京', '上海', '广州', '南京', '武汉']

let inters = setA.intersection(setB);
console.log(inters.values()); // ['北京']

let diffs = setA.different(setB);
console.log(diffs.values()); // ['上海', '广州']

最后再测试一下子集:

let issub = setA.isSubsetOf(setB);
console.log(issub); // false

let setC = new Set();
setC.add("上海");
issub = setA.isSubsetOf(setC);
console.log(issub); // true

测试通过,完美实现!

三、总结

通过两篇文章介绍了集合的相关知识,你学会了吗?虽然 ES6 提供了原生支持,但是对于我们学习者来说,手动实现一次更有助于了解原理。

到此这篇关于JavaScript 数据结构之集合创建(2)的文章就介绍到这了,更多相关JavaScript集合内容请搜索我们以前的文章或继续浏览下面的相关文章希望大家以后多多支持我们!

(0)

相关推荐

  • JavaScript中的Map数据结构详解

    目录 1. 什么是 Map 2. Map 构造函数 2.1) 数组 2.2) Set 2.3) Map 3. Map 的实例属性和方法 3.1) Map 的属性 size 3.2) Map 的方法 set get has delete clear forEach 4. Map的注意事项 5. Map的使用场景 总结 1. 什么是 Map Map 就是映射的意思,即从键到值的映射. Map 保存键值对,并且能够记住键的原始插入顺序. 那么它和 Object 有什么区别 ? 对象一般用字符串作键 c

  • JS使用reduce()方法处理树形结构数据

    定义 reduce() 方法对数组中的每个元素执行一个由您提供的reducer函数(升序执行),将其结果汇总为单个返回值. reduce() 与forEach().map().filter()这些方法一样,也会对数组中的每一项进行遍历,但是reduce() 可以将遍历的前一个数组项产生的结果与当前遍历项进行运算. 语法 array.reduce(function(prev, cur, index, array){ ... }, init); 回调函数中的参数: prev 必需.表示调用回调时的返

  • Go语言的数据结构转JSON

    目录 结构体转为 JSON 格式 接口转为 JSON 格式 Marshal() 函数的原型 总结 在日常工作中,除了需要从 JSON 转化为 Go 的数据结构.但往往相反的情况是:我们需要将数据以 JSON 字符串的形式发送到 Web 服务器.今天我们将学会如何从一个结构化数据编码为 JSON . Json(Javascript Object Nanotation)是一种数据交换格式,常用于前后端数据传输.任意一端将数据转换成json 字符串,另一端再将该字符串解析成相应的数据结构,如strin

  • 一组JS创建和操作表格的函数集合

    stone.js //**************************************神吹表格操作函数******************************************************* //隐藏列 function setHiddenRow(tb,iCol){ for (i=0;i<oTable.rows.length;i++){ tb.rows[i].cells[iCol].style.display = oTable.rows[i].cells[iCo

  • JavaScript 数据结构 之集合创建

    目录 一.什么是集合 二.创建集合类 1.has 方法 2.add 方法 3.delete 和 clear 方法 4.size 方法 5.values 方法 三.使用集合 总结 前言: 集合这个词应该比较耳熟,大多数人没接触代码前就学过了.回想一下你的高一数学课本上是不是出现过这个词,就在第一章,概念如下: 一般地,我们把研究的对象统称为元素,把一些元素组成的总体叫作集合. 你看,集合,元素,是不是与今天我们学习的数据结构相通呢? 一.什么是集合 集合是由一组无序且唯一(不能重复)的元素组成.数

  • JavaScript 数据结构之集合创建(2)

    目录 前言 一.集合运算 1.并集 2.交集 3.差集 4.子集 二.使用集合运算 三.总结 前言 上一篇JavaScript 数据结构 之集合创建(1)我们介绍了什么是集合,并且手动实现了一个集合的类.简单总结,集合就是一组元素唯一,并且没有顺序的数据集,关键是元素唯一. ES6 提供了原生的集合支持,就是新增的 Set 数据类型.其实在上篇我们几乎已经实现了 Set 的所有功能,如果还不了解集合,请看上篇内容 但是我们也说到,Set 的基本功能中不包含数学运算如 交集,并集,差集,事实上这也

  • JavaScript 数据结构之字典方法

    目录 一.什么是字典 二.创建字典类 1.hasKey 方法 2.set 方法 3.remove 方法 4.get 方法 5.keys, values, keyValues 方法 6.forEach 方法 7.clear, size, isEmpty 方法 三.使用字典 四.总结 前言: 经过上一篇JavaScript 数据结构之集合创建(2)的学习,数据结构的集合部分已经完结了.那么下面我们又要认识一个新的数据结构,它的名字相信你绝不陌生,它就是字典. 这个字典可不是查汉字时用的那个字典.字典

  •  JavaScript 数据结构之散列表的创建(2)

    目录 一.处理散列值冲突 1.分离链接 2.put 方法 3.get 方法 前言: 上一篇我们介绍了什么是散列表,并且用通俗的语言解析了散列表的存储结构,最后动手实现了一个散列表,相信大家对散列表已经不陌生了. 如果还不清楚散列表,请先阅读上一篇文章:JavaScript 数据结构之散列表的创建(1) 上篇末尾我们遗留了一个问题,就是将字符串转化为散列值后可能出现重复.当以散列值(hash 值)为 key 存储数据时,就会有覆盖已有数据的风险.本篇我们看如何处理散列值冲突的问题,并实现更完美的散

  • javascript数据结构之多叉树经典操作示例【创建、添加、遍历、移除等】

    本文实例讲述了javascript数据结构之多叉树经典操作.分享给大家供大家参考,具体如下: 多叉树可以实现复杂的数据结构的存储,通过遍历方法可以方便高效的查找数据,提高查找的效率,同时方便管理节点数据.javascript的DOM其实就是以多叉树的形式存储的.下面用javascript来实现多叉树的数据结构 1.创造一个节点 数据是以节点的形式存储的: class Node { constructor(data) { this.data = data; this.parent = null;

  • JavaScript数据结构与算法之栈与队列

    学习起因 曾经有一次在逛V2EX时,碰到这么一个帖子. 数学完全还给老师了,想学回一些基础数学,大概是高中程度的,有什么书籍推荐? 发帖的楼主大学没有高数课程,出去工作时一直在从事前端的工作.感觉到数学知识的匮乏,所以想补一补数学. 看了看帖子,感觉和我很像,因为我的专业是不开高数的,我学的也是前端.也同样感觉到了数学知识匮乏所带来的困顿.同时因为自己的数学思维实在是不怎么好,所以决定努力补习数学与计算机基础知识. 当时也有人说:"前端需要什么数据结构与算法",但是对于这个事情我有自己

  • JS中的算法与数据结构之集合(Set)实例详解

    本文实例讲述了JS中的算法与数据结构之集合(Set).分享给大家供大家参考,具体如下: 集合(Set) 同数学中所学的一样,集合(Set)是由一组无序但彼此之间又有一定关系性的成员构成,每个成员在集合中只能出现一次,不同于我们之前说的字典,链表之类的,它是一种包含了不同元素的数据结构(集合中的元素称为成员),从其定义中我们可以看出它具有两个很重要的特征:首先,集合中的成员是无序的,其次,集合中的成员是不相同的,即集合中不存在相同的成员. 实际上,很多编程语言中,集合并不是一种数据类型,但是如果你

  • JavaScript字典与集合详解

    目录 字典 什么是字典 JavaScript中的字典 字典的应用 集合 什么是集合 JS中的集合 集合中的操作 交集.并集.差集的封装 字典 什么是字典 说到字典,第一时间想到的应该就是新华字典,实际上,这跟编程中的字典类似,两者都有一个特点,就是一一对应(yi yi dui ying),或者说是映射. 字典通常以**[键,值]** 对的形成存储,因为是以键值对的形式存储,更方便通过key来获取value 比如存储用户信息: { 'username': '一碗周', 'age': 18 } Ja

  • javascript中的对象创建 实例附注释

    javascript中的对象创建声明: var obj = {}; 或者 var obj = new Object(); 为对象加入属性,方法: //=====第一种写法==================================== obj.name = '小明'; //为对象加属性 obj.updateName = function(name){//为对象定义updateName方法 this.name = name; } alert(obj.name); obj.updateNam

  • JavaScript数据结构之二叉查找树的定义与表示方法

    本文实例讲述了JavaScript数据结构之二叉查找树的定义与表示方法.分享给大家供大家参考,具体如下: 树是一种非线性的数据结构,以分层的方式存储数据.树被用来存储具有层级关系的数据,比如文件系统中的文件:树还被用来存储有序列表.这里将研究一种特殊的树:二叉树.选择树而不是那些基本的数据结构,是因为在二叉树上进行查找非常快(而在链表上查找则不是这样),为二叉树添加或删除元素也非常快(而对数组执行添加或删除操作则不是这样). 树是n个结点的有限集.最上面的为根,下面为根的子树.树的节点包含一个数

随机推荐