ES6 Set数据结构的使用

ES6 内 的数据结构Set

特性:类似数组,但是它的最大特性就是所有元素都是唯一的,没有重复的值

Set本身是一个构造函数,用来生成Set数据结构。

const s = new Set();

[2,3,3,5,6,7,7,4,3].forEach( x => s.add(x));

for(let i of s){
    console.log(i);
}
//2 3 5 6 7 4

可以看到通过add()向Set结构内添加数据,返回的Set结构内无重复数据。

Set函数可以接受一个数组作为参数,用来初始化。

const set = new Set([1,2,3,4,4]);

set ;   // [ Set { 1, 2, 3, 4 } ]

[...set];   //[ 1, 2, 3, 4 ]     解构获取Set内部的值
  
set.size;   // 4      set的长度获取

数组去重也可这样做:

// 去除数组的重复成员
[...new Set(array)]

除了单数组去重以外,也可进行多数组合并去重:

let arr1 = [1, 2, 3, 4]
let arr2 = [2, 3, 4, 5, 6]
let setc = new Set([...arr1, ...arr2])
console.log("set",setc)

//setc: Set { 1, 2, 3, 4, 5, 6 }

上述单数组去重的方法,也可用于字符串去重:

[...new Set('ababbc')].join('')
// "abc"

向Set添加数据的三种情况:

//情况1
let set = new Set();
set.add("5");
set.add(5);
set        //Set { '5', 5 }

//情况2
let set1 = new Set();
let a = NaN;
let b = NaN;
set1.add(a);
set1.add(b);
set1        //Set { NaN }

//情况3
let set2 = new Set();
set2.add({});
set2.size    //1
set2.add({})
set2.size    //2
set2        //Set { {}, {} }

 上述代码表示:向 Set 加入值的时候,不会发生类型转换,所以5"5"是两个不同的值。

Set 内部判断两个值是否不同,使用的算法叫做“Same-value-zero equality”,它类似于精确相等运算符(===),主要的区别是向 Set 加入值时认为NaN等于自身,而精确相等运算符认为NaN不等于自身。

由于两个空对象不相等,所以它们被视为两个值。

Set的实例属性和方法

Set结构的实例有以下属性:

  1. constructor: 构造函数,默认是Set函数
  2. size: 返回Set实例的成员总数

Set实例的方法分为两大类:操作方法(用于操作数据)和遍历方法(用于遍历成员)。

1.add(value): 添加某个值,返回Set结构本身。

let set = new Set();
set.add("5");
set.add(5);
set        //Set { '5', 5 }

2.delete(value): 删除某个值,返回布尔值,表示删除是否成功。

3.has(value): 返回一个布尔值,表示该值是否为Set成员。

let set = new Set();
set.add("5");
set.add(5);
set        // Set { '5', 5 }

set.delete('5');   //删除5
set        // Set { 5 }

// 判断Set是否有该元素
set.has(5);        // true    是set的成员
set.has('5');      // false    不是set的成员,已经被删掉了

4.clear(): 清除所有成员,没有返回值。

let set = new Set();
set.add("5");
set.add(5);
set        // Set { '5', 5 }
set.clear()  //  Set {}

Object结构与Set结构的对比:

// 对象的写法
const properties = {
  'width': 1,
  'height': 1
};

if (properties[someName]) {
  // do something
}

// Set的写法
const properties = new Set();

properties.add('width');
properties.add('height');

if (properties.has(someName)) {
  // do something
}

数组转Set结构

const items = new Set([1, 2, 3, 4, 5]);
const array = Array.from(items);

这也提供了数组去重的另一种方法:

function dedupe(array) {
  return Array.from(new Set(array));
}

dedupe([1, 1, 2, 3]) // [1, 2, 3]

遍历操作

Set结构的实例有四个遍历方法,可以用于遍历成员。

  1. keys():  返回键名的遍历器
  2. values(): 返回键值的遍历器
  3. entries(): 返回键值对的遍历器
  4. forEach(): 使用回调函数遍历每个成员

需要特别指出的是,Set的遍历顺序就是插入顺序。这个特性有时非常有用,比如使用 Set 保存一个回调函数列表,调用时就能保证按照添加顺序调用。

由于Set的键名和键值是同一个值,它的每一个元素的key和value是相同的,所有keys()和values()的返回值是相同的,entries()返回的元素中的key和value是相同的。

let set = new Set(['1', '2', '3']);

for (let item of set.keys()) {
  console.log(item);
}
// 1
// 2
// 3

for (let item of set.values()) {
  console.log(item);
}
// 1
// 2
// 3

for (let item of set.entries()) {
  console.log(item);
}
//[ '1', '1' ]
//[ '2', '2' ]
//[ '3', '3' ]

Set 结构的实例默认可遍历,它的默认遍历器生成函数就是它的values方法。

Set.prototype[Symbol.iterator] === Set.prototype.values
// true

forEach:

let set = new Set([1, 4, 9]);
set.forEach((value, key) => console.log(key + ' : ' + value))
// 1 : 1
// 4 : 4
// 9 : 9

扩展运算符和Set结构相结合,就可以去除数组的重复成员。

let arr = [1,2,3,3,4,5];
let unique = [...new Set(arr)];
// [1,2,3,4,5]

数组的map和filter也可用于Set结构。

let set = new Set([1,2,3]);
set = new Set([...set].map(x => x*2));
// Set { 2, 4, 6 }

let set = new Set([1,2,3,4,5]);
set = new Set([...set].filter(x => x % 2 == 0));
console.log(set);
// Set { 2, 4 }

使用Set结构很容易实现并集(Union)、交集(Intersect)和差集(Difference)。

let a = new Set([1,2,3]);
let b = new Set([3,4,5]);

// 并集
let union = new Set([...a, ...b]);
union           // Set { 1, 2, 3, 4, 5 }

//交集
let intersect = new Set([...a].filter(x =>b.has(x)));
intersect       //Set { 3 }

//差集
let difference = new Set([...a].filter(x => !b.has(x)));
difference      // Set { 1, 2 }

  详细请查看ES6 Set教程

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

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

余额充值