TypeScript方式实现源码
// 特性:
// 1. 集合是由一组无序且唯一(即不能重复)的项组成的。这个数据结构使用了与有限集合相同的数学概念,但应用在计算机科学的数据结构中。
// 2. 也可以把集合想象成一个既没有重复元素,也没有顺序概念的数组
// 3. 在数学中,集合也有并集、交集、差集等基本操作。在这一章中我们也会介绍这些操作 // 集合操作
// 并集:对于给定的两个集合,返回一个包含两个集合中所有元素的新集合
// 并集的数学概念,集合A和B的并集,表示为A∪B,定义如下:
// A∪B = { x | x ∈ A∨x ∈ B }
// 意思是x(元素)存在于A中,或x存在于B中。下图展示了并集操作:
// 并集.png // 交集:对于给定的两个集合,返回一个包含两个集合中共有元素的新集合
// 交集的数学概念,集合A和B的交集,表示为A∩B,定义如下:
// A∩B = { x | x ∈ A∧x ∈ B }
// 意思是x(元素)存在于A中,且x存在于B中。下图展示了交集操作:
// 交集.png // 差集:对于给定的两个集合,返回一个包含所有存在与第一个集合且不存在与第二个集合的元素的新集合
// 差集的数学概念,集合A和B的差集,表示为AB,定义如下:
// AB = { x | x ∈ A ∧ x B }
// 意思是x(元素)存在于A中,且x不存在于B中。下图展示了集合A和B的差集操作:
// 差集.png // 子集:验证一个给定集合是否是另一个集合的子集
// 最后一个集合操作是子集。子集的数学概念,集合A是B的子集(或集合B包含
// 了A) ,表示为A⊆B,定义如下:
// ∀x { x ∈ A → x ∈ B }
// 意思是集合A中的每一个x(元素) ,也需要存在于B中。下图展示了集合A是集合B的子集:
// 子集.png
 class Set {
private items: Object = {};
/**
* 向集合添加一个新的项
* @param value
*/
public add(value) {
if (!this.has(value)) {
this.items[value] = value;
return true;
}
}
/**
* 从集合移除一个值
* @param value
*/
public remove(value) {
if (this.has(value)) {
delete this.items[value];
return true;
}
return false;
}
/**
* 如果值在集合中,返回true,否则返回false
* @param value
*/
public has(value) {
return this.items.hasOwnProperty(value);
}
/**
* 移除集合中的所有项
*/
public clear() {
this.items = {};
}
/**
* 返回集合所包含元素的数量。与数组的length属性类似
*/
public size() {
var count = ;
for (var prop in this.items) { //{5}
if (this.items.hasOwnProperty(prop)) //{6}
++count; //{7}
}
return count;
}
/**
* 返回一个包含集合中所有值的数组
*/
public values() {
var keys = [];
for (var key in this.items) { //{7}
keys.push(key); //{8}
}
return keys;
}
public union(otherSet: Set): Set {
let unionSet = new Set(); let values = this.values();
for (let i = ; i < values.length; i++) {
unionSet.add(values[i]);
} values = otherSet.values();
for (let i = ; i < values.length; i++) {
unionSet.add(values[i]);
}
return unionSet;
}
public intersection(otherSet: Set) {
let intersectionSet = new Set();
let values = this.values();
for (let i = ; i < values.length; i++) {
if (otherSet.has(values[i])) {
intersectionSet.add(values[i]);
}
}
return intersectionSet;
}
public difference(otherSet: Set) {
let differenceSet = new Set();
let values = this.values();
for (let i = ; i < values.length; i++) {
if (!otherSet.has(values[i])) {
differenceSet.add(values[i]);
}
}
return differenceSet;
}
public subset(otherSet: Set) {
if (this.size() > otherSet.size()) {
return false;
} else {
let values = this.values();
for (let i = ; i < values.length; i++) {
if (!otherSet.has(values[i])) {
return false;
}
}
return true;
}
} }
 // 使用 Set 类
let set = new Set(); set.add();
console.log(set.values()); //输出["1"]
console.log(set.has()); //输出true
console.log(set.size()); //输出1 set.add();
console.log(set.values()); //输出["1", "2"]
console.log(set.has()); //true
console.log(set.size()); //2 set.remove();
console.log(set.values()); //输出["2"] set.remove();
console.log(set.values()); //输出[] // 测试一下并集的代码:
var setA = new Set();
setA.add();
setA.add();
setA.add(); var setB = new Set();
setB.add();
setB.add();
setB.add();
setB.add(); var unionAB = setA.union(setB);
console.log(unionAB.values()); // 测试一下交集的代码
var setA = new Set();
setA.add();
setA.add();
setA.add(); var setB = new Set();
setB.add();
setB.add();
setB.add(); var intersectionAB = setA.intersection(setB);
console.log(intersectionAB.values());
//输出为["2", "3"],因为2和3同时存在于两个集合中 // 测试一下差集的代码
var setA = new Set();
setA.add();
setA.add();
setA.add(); var setB = new Set();
setB.add();
setB.add();
setB.add(); var differenceAB = setA.difference(setB);
console.log(differenceAB.values());
//输出为["1"],因为1是唯一一个仅存在于setA的元素。 // 测试一下子集的代码
var setA = new Set();
setA.add();
setA.add(); var setB = new Set();
setB.add();
setB.add();
setB.add(); var setC = new Set();
setC.add();
setC.add();
setC.add(); console.log(setA.subset(setB));
console.log(setA.subset(setC));
// 我们有三个集合:setA是setB的子集 (因此输出为true) , 然而setA不是setC的子集 (setC
// 只包含了setA中的2,而不包含1) ,因此输出为false

使用 Set 类

总结:我们将从头实现一个与ECMAScript 6中定义的类似的Set类。我们还介绍了在其他编程语言的集合数据结构的实现中不常见的一些方法,比如并集、交集、差集和子集。因此,相比于其他编程语言目前的Set实现,我们实现了一个非常完备的Set类

JavaScript方式实现源码
 var Set = (function () {
function Set() {
this.items = {};
}
/**
* 向集合添加一个新的项
* @param value
*/
Set.prototype.add = function (value) {
if (!this.has(value)) {
this.items[value] = value;
return true;
}
};
/**
* 从集合移除一个值
* @param value
*/
Set.prototype.remove = function (value) {
if (this.has(value)) {
delete this.items[value];
return true;
}
return false;
};
/**
* 如果值在集合中,返回true,否则返回false
* @param value
*/
Set.prototype.has = function (value) {
return this.items.hasOwnProperty(value);
};
/**
* 移除集合中的所有项
*/
Set.prototype.clear = function () {
this.items = {};
};
/**
* 返回集合所包含元素的数量。与数组的length属性类似
*/
Set.prototype.size = function () {
var count = ;
for (var prop in this.items) {
if (this.items.hasOwnProperty(prop))
++count; //{7}
}
return count;
};
/**
* 返回一个包含集合中所有值的数组
*/
Set.prototype.values = function () {
var keys = [];
for (var key in this.items) {
keys.push(key); //{8}
}
return keys;
};
Set.prototype.union = function (otherSet) {
var unionSet = new Set();
var values = this.values();
for (var i_1 = ; i_1 < values.length; i_1++) {
unionSet.add(values[i_1]);
}
values = otherSet.values();
for (var i_2 = ; i_2 < values.length; i_2++) {
unionSet.add(values[i_2]);
}
return unionSet;
};
Set.prototype.intersection = function (otherSet) {
var intersectionSet = new Set();
var values = this.values();
for (var i_3 = ; i_3 < values.length; i_3++) {
if (otherSet.has(values[i_3])) {
intersectionSet.add(values[i_3]);
}
}
return intersectionSet;
};
Set.prototype.difference = function (otherSet) {
var differenceSet = new Set();
var values = this.values();
for (var i_4 = ; i_4 < values.length; i_4++) {
if (!otherSet.has(values[i_4])) {
differenceSet.add(values[i_4]);
}
}
return differenceSet;
};
Set.prototype.subset = function (otherSet) {
if (this.size() > otherSet.size()) {
return false;
}
else {
var values = this.values();
for (var i_5 = ; i_5 < values.length; i_5++) {
if (!otherSet.has(values[i_5])) {
return false;
}
}
return true;
}
};
return Set;
}());

JavaScript数据结构与算法(八) 集合(ECMAScript 6中定义的类似的Set类)的更多相关文章

  1. JavaScript 数据结构与算法之美 - 非线性表中的树、堆是干嘛用的 ?其数据结构是怎样的 ?

    1. 前言 想学好前端,先练好内功,内功不行,就算招式练的再花哨,终究成不了高手. 非线性表(树.堆),可以说是前端程序员的内功,要知其然,知其所以然. 笔者写的 JavaScript 数据结构与算法 ...

  2. javascript数据结构与算法-- 二叉树

    javascript数据结构与算法-- 二叉树 树是计算机科学中经常用到的一种数据结构.树是一种非线性的数据结构,以分成的方式存储数据,树被用来存储具有层级关系的数据,比如文件系统的文件,树还被用来存 ...

  3. 为什么我要放弃javaScript数据结构与算法(第六章)—— 集合

    前面已经学习了数组(列表).栈.队列和链表等顺序数据结构.这一章,我们要学习集合,这是一种不允许值重复的顺序数据结构. 本章可以学习到,如何添加和移除值,如何搜索值是否存在,也可以学习如何进行并集.交 ...

  4. JavaScript数据结构与算法-集合练习

    集合的实现 function Set () { this.dataStore = []; this.add = add; this.remove = remove; this.size = size; ...

  5. 重读《学习JavaScript数据结构与算法-第三版》-第2章 ECMAScript与TypeScript概述

    定场诗 八月中秋白露,路上行人凄凉: 小桥流水桂花香,日夜千思万想. 心中不得宁静,清早览罢文章, 十年寒苦在书房,方显才高志广. 前言 洛伊安妮·格罗纳女士所著的<学习JavaScript数据 ...

  6. 为什么我要放弃javaScript数据结构与算法(第一章)—— JavaScript简介

    数据结构与算法一直是我算比较薄弱的地方,希望通过阅读<javaScript数据结构与算法>可以有所改变,我相信接下来的记录不单单对于我自己有帮助,也可以帮助到一些这方面的小白,接下来让我们 ...

  7. 重读《学习JavaScript数据结构与算法-第三版》- 第4章 栈

    定场诗 金山竹影几千秋,云索高飞水自流: 万里长江飘玉带,一轮银月滚金球. 远自湖北三千里,近到江南十六州: 美景一时观不透,天缘有分画中游. 前言 本章是重读<学习JavaScript数据结构 ...

  8. JavaScript 数据结构与算法之美 - 线性表(数组、栈、队列、链表)

    前言 基础知识就像是一座大楼的地基,它决定了我们的技术高度. 我们应该多掌握一些可移值的技术或者再过十几年应该都不会过时的技术,数据结构与算法就是其中之一. 栈.队列.链表.堆 是数据结构与算法中的基 ...

  9. 为什么我要放弃javaScript数据结构与算法(第十一章)—— 算法模式

    本章将会学习递归.动态规划和贪心算法. 第十一章 算法模式 递归 递归是一种解决问题的方法,它解决问题的各个小部分,直到解决最初的大问题.递归通常涉及函数调用自身. 递归函数是像下面能够直接调用自身的 ...

随机推荐

  1. Python类中的self到底是干啥的

    Python类中的self到底是干啥的 Python编写类的时候,每个函数参数第一个参数都是self,一开始我不管它到底是干嘛的,只知道必须要写上.后来对Python渐渐熟悉了一点,再回头看self的 ...

  2. APK Multi-Tool强大的APK反编译工具终极教程

    一.APK Multi-Tool介绍    APK Multi-Tool 是APK Manager的升级版,是一个强大的APK反编译工具,集多种功能于一身,是居家必备.做ROM必选的工具!    这是 ...

  3. 【RabbitMQ系列】队列、绑定、交换器

    队列: 从概念上来讲,AMQP消息路由必须有三部分:交换器.队列和绑定.生产者把消息发布到交换器上:消息最终到达队列,并被消费者接收:绑定决定了消息如何从路由器路由到特定的队列. 消费者通过以下两种方 ...

  4. alpha冲刺第四天

    一.合照 二.项目燃尽图 三.项目进展 今天实现了登录界面和服务器的连接了,牵手成功. 一些具体的界面细化实现,一些button的响应实现 四.明日规划 登录界面和服务器的连接实现耗费了太多时间,接下 ...

  5. beta冲刺6-咸鱼

    前言:此篇是补昨天凌晨的.后面有更新但是太晚了就没有即使更新.所以现在过来更新一下. 昨天的未完成: 用户测试+测试报告 目前剩下的功能点:输入内容检测 我的社团输出显示格式调整. 今天的完成: 我的 ...

  6. c语言博客作业-指针

    一.PTA实验作业 题目1: 1. 本题PTA提交列表 2. 设计思路(用代码表示扣分) 定义整型变量i,count记录平均分,实型变量sum保存总分 for i=0 to n sum = sum+* ...

  7. TRY

  8. Flask 学习 十 博客文章

    提交和显示博客文章 app/models.py 文章模型 class Post(db.Model): __tablename__ = 'posts' id = db.Column(db.Integer ...

  9. 04_Linux目录文件操作命令1(mv ls cd...)_我的Linux之路

    上一节已经给大家讲了Linux的目录结构,相信大家已经对Linux的整个目录结构有所了解 现实中,服务器(包含Linux,Unix,windows server)一般都摆放在机房里,因为一个机房摆放了 ...

  10. 说说cglib动态代理

    前言 jdk中的动态代理通过反射类Proxy和InvocationHandler回调接口实现,要求委托类必须实现一个接口,只能对该类接口中定义的方法实现代理,这在实际编程中有一定的局限性. cglib ...