ES6之Set集合的使用

在许多实际问题中,我们必须处理一种集合,集合中的每个元素都是唯一的(每个元素只能出现一次),这种集合称之为Set。在ES6之前,这种集合只能通过模拟实现。

console.log("------------------Set--------------------");
//使用对象存储数据
function Set() {
  this.data = {};
  this.length = 0;
}

//检查元素是否存在
Set.prototype.has = function (item) {
  return typeof this.data[item] !== 'undefined';
}

//当Set中不存在元素时,才进行添加
Set.prototype.add = function (item) {
  if (!this.has(item)) {
    this.data[item] = true;
    this.length++;
  }
}

//如果Set中已经存在元素,则删除
Set.prototype.remove = function (item) {
  if (this.has(item)) {
    delete this.data[item];
    this.length--;
  }
}

//试图添加两次Hattori
const ninjasSet = new Set();
ninjasSet.add("Hattori");
ninjasSet.add("Hattori");

//验证只存在一个Hattori
if (ninjasSet.has("Hattori") && ninjasSet.length === 1) {
  console.log("Our set contains only one Hatttori");
}

//删除Hattori,并验证已被删除成功
ninjasSet.remove("Hattori");
if (!ninjasSet.has("Hattori") && ninjasSet.length === 0) {
  console.log("Our set is now empty!");
}

 

上面的例子显示了如何通过对象模拟Set的简单示例。使用对象存储数据,持续跟踪集合中的元素,提供三个方法:has,验证集合中是否存在元素;add,如果集合中不存在元素则将元素添加到集合中;remove,删除集合中已经存在的元素。

但这仅仅是模拟,因为(对象)Set不能真正地存储对象,只能存储字符串或数字,

//因为此时的(对象)Set不能真正地存储对象,只能存储字符串或数字,仍然存在访问原型对象的风险。

Set是ES6标准的一部分,可访问http://mng.bz/JYYM查看浏览器兼容性。

 

创建Set

创建Set的方法是使用构造函数:Set。

//Set构造函数接收数组进行初始化
const ninjaSet = new Set(['Kuma', 'Hattori', 'Yagyu', 'Hattori']);
if (ninjaSet.has('Hattori')) {
  console.log("Hattori is in our set");
}
//验证丢弃重复项
if (ninjaSet.size === 3) {
  console.log("There are only three ninjas in our set!");
}

//可以向集合中添加不存在的元素
if (!ninjaSet.has("Yoshi")) {
  console.log("Yoshi is not in, yet...");
}

ninjaSet.add("Yoshi");

if(ninjaSet.has("Yoshi")) {
  console.log("Yoshi is added");
}

if (ninjaSet.size === 4) {
  console.log("There are four ninjas in our set");
}

//向集合中添加已经存在的元素将不起作用
if (ninjaSet.has("Kuma")) {
  console.log("Kuma is already added");
}
ninjaSet.add("Kuma");
if (ninjaSet.size === 4) {
  console.log("Adding Kuma again has no effect");
}

//通过for...of循环对集合进行遍历
for (let ninja of ninjaSet) {
  if (ninja !== null) {
    console.log(ninja);
  }
}

 

 

 

 

使用内置构造函数创建Set。如果不传入任何参数,将创建一个空Set。可以传入字符串:

const ninjaSet = new Set(['Kuma', 'Hattori', 'Yagyu', 'Hattori']);

Set成员的值都是唯一的,最重要的作用是避免存储多个相同的对象。本例中试图添加两次"Hattori",但是只成功添加一次。

Set具有多个可访问的方法。例如,has方法验证Set中是否存在元素。

ninjaSet.has("Yoshi")

add方法用于添加唯一成员

ninjaSet.add("Kuma");

如果要知道Set中有几个元素,可以使用size属性。

与Map和数组类似,Set也是集合,因此可以使用for-of循环进行遍历,成员的遍历与插入顺序一致。

查看Set集合的一些常见操作:并集(Union)、交集(Intersect)和差集(Difference)。

并集

两个集合的并集指的是创建一个新的集合,同时包含A和B中的所有成员。当然,在新的集合中的元素也不允许出现两次。

console.log("__________________并集______________________");
//创建两个数组ninjas与samurai。注意Hattori在两个数组中均存在

const ninjaSetA = ['Kuma', "Hattori", 'Yagyu'];
const samurai = ['Hattori', 'Oda', 'Tomoe'];

//创建两个数组的并集
const warriors = new Set([...ninjaSetA, ...samurai]);

if (warriors.has('Kuma')) {
  console.log('Kuma is here');
}

if (warriors.has('Hattori')) {
  console.log("And Hattori");
}

if (warriors.has('Yagyu')) {
  console.log('And Yagyu');
}

if (warriors.has('Oda')) {
  console.log('And Oda');
}

if (warriors.has('Tomoe')) {
  console.log("Tomoe, last but not least");
}

//集合中没哟重复元素。虽然在两个数组中都存在Hattori,但是并集中只有一个
if (warriors.size === 5) {
  console.log("There are 5 warriors in total!");
}

 

 

首先创建两个数组ninjaSetA与samurai,两个数组中都具有Hattori元素。假设我们同时需要两个数组中的元素,因此,我们需要创建一个新的Set,同时包含ninjaSet与samurai两个数组中的元素。虽然两个数组中都存在Hattpri元素,但是集合中只有一个Hattori元素。

在本例中,使用Set是最完美的。不需要手动判断元素是否已经存在:Set会自动处理。当创建新的Set时,我们使用延展运算符[...ninjaSetA, ...samurai]创建包含两个数组的Set。

交集

两个集合的交集指的是创建新集合,该集合中只包含集合A与B中同时出现的成员。

console.log("-------------------交集------------------------");
const ninjaSetB = new Set(['Kuma', "Hattori", 'Yagyu']);
const ninjaSetC = new Set(['Hattori', 'Oda', 'Tomoe']);

//使用延展运算符将集合转换为数组,以便调用数组的filter方法,保留ninjaSetB中同时在ninjaSetC中出现的元素
//创建新数组
const ninjaSetBC = new Set([...ninjaSetB].filter(ninja =>
  ninjaSetC.has(ninja)
));

if (ninjaSetBC.size === 1) {
  console.log("There is only one ninjaSetBC!");
}

if (ninjaSetBC.has("Hattori")) {
  console.log("Hattori is his name");
}

主要思想是创建一个新集合,该集合中只包含nijaSetB数组与nijaSetC数组中同时存在的元素。通过数组的filter方法,使得数据中的元素都符合回调函数中指定的特定条件。在本例中,指定的条件是元素在ninjaSetB数组与ninjaSetC数组中同时存在,filter方法只能操作数组,我们使用延展运算符将Set转换为数组:[...ninjaSetB]

最后,验证找到ninjaB数组与nijaC数据中同时存在的元素:Hattori。

 

差集

两个集合的差集指的是创建新集合,只包含存在集合A、但不在集合B中的元素。这类似于集合的交集,但具有一个小的但是重要的差异。

console.log("-----------------差集-----------------------");
const nijaSetD = new Set(['Kuma', "Hattori", 'Yagyu']);
const nijaSetF = new Set(['Hattori', 'Oda', 'Tomoe']);

const pureNinjas = new Set(
  [...nijaSetD].filter(ninja => !nijaSetF.has(ninja))
);

if (pureNinjas.size === 2) {
  console.log("There is only one ninjaD ninjaF");
}
if (pureNinjas.has('Kuma')) {
  console.log("Kuma is a true ninja");
}
if (pureNinjas.has('Yagyu')) {
  console.log("Yagyu is a true ninja");
}
console.log("pureNinjas:" + pureNinjas);

 

在表示式nijaSetF.has(ninja)前面添加"!",就得到了想要的差集。

参考:JavaScript忍者秘籍

猜你喜欢

转载自blog.csdn.net/zhangying1994/article/details/84196391
今日推荐