我们相信:世界是美好的,你是我也是。平行空间的世界里面,不同版本的生活也在继续...

本文描述一下JavaScript里面的set数据类型,在以前的文章中,苏南大叔描述过Python里面的set数据类型,可以知道:set是一种天然去重并且无序的类型。那么,在JavaScript中,set也具有天然去重的特点,但是却没有表现出无序的状态。

苏南大叔:JavaScript,如何理解具有天然去重特性的set数据类型? - js-set
JavaScript,如何理解具有天然去重特性的set数据类型?(图6-1)

苏南大叔的程序如此灵动博客,记录苏南大叔和计算机代码的故事。测试缓解:node@16.14.2

定义set

先对比一下下面的两个定义方式:

let _set2 = new Set("sunan");
let _set3 = new Set("sunan","苏南");
let _set4 = new Set(["sunan","苏南"]);
console.log("set2:",_set2);   // Set(4) { 's', 'u', 'n', 'a' }
console.log("set3:",_set3);   // Set(4) { 's', 'u', 'n', 'a' }
console.log("set4:",_set4);   // Set(2) { 'sunan', '苏南' }

苏南大叔:JavaScript,如何理解具有天然去重特性的set数据类型? - 正确的定义方式
JavaScript,如何理解具有天然去重特性的set数据类型?(图6-2)

从这两个方式可以看出,

  • 传入一个字符串,字符串被分解成了多个单字符,并同时符合去重特性。
  • 传入两个字符串,第二个字符串参数完全失效,完全没有效果。第一个字符串被分解成多个单个字符。
  • 传入是个数组时,数组成员就是set成员,且去重。(数组成员可以重复,但是set成员不可以重复)。

当然,也可以直接定义一个空的set

const _set = new Set();
// _set.add("s");

添加.add、删除.delete以及修改

对比map类型的话,添加的方式换成.add()【这个是map的最明显区别!】
如果要修改一个数据,可以先删除,再添加。【毕竟是不可以重复的,不必担心误操作】

const _set = new Set();
_set.add('苏南');
console.log(_set);              // Set(1) { '苏南' }
console.log(_set.has('苏南'));  // true
_set.delete('苏南');
console.log(_set);              // Set(0) {}

苏南大叔:JavaScript,如何理解具有天然去重特性的set数据类型? - js-set-add-delete
JavaScript,如何理解具有天然去重特性的set数据类型?(图6-3)

在这个例子中,如果添加的对象是个稍稍复制的成员的话(比如数组,就会出问题),.has()监测不到,.delete()也删除不了,必须保持原始对象的引用。

const _set = new Set();
let a = ["su", "n", "a", "n"];
_set.add(a);

console.log(_set.has(a));                      // true
console.log(_set.has(["su", "n", "a", "n"]));  // false

_set.delete(["su", "n", "a", "n"]);
console.log(_set);    // Set(1) { [ 'su', 'n', 'a', 'n' ] }

_set.delete(a);
console.log(_set);    // Set(0) {}

苏南大叔:JavaScript,如何理解具有天然去重特性的set数据类型? - 一个小坑
JavaScript,如何理解具有天然去重特性的set数据类型?(图6-4)

挖坑了不是?所以,个人认为,除了数字字符之类的普通成员,其他的都最好特殊处理一下(比如序列化serialize)比较好。待后续文字补充。

.keys.values

非常令人意外的是:JavaScript里面的set()居然有key。而且根据测试的结果,.keys.values数据完全一致,都是迭代器类型的。(也许这可能就是JavaScript里面的set天然去重的实现手段,毕竟keys是从来没听说过会有重复的。)

const _set = new Set();
_set.add('苏南');
console.log(_set.size);       // 1
console.log(_set.keys());     // [Set Iterator] { '苏南' }
console.log(_set.values());   // [Set Iterator] { '苏南' }
console.log(_set.entries());  // [Set Entries] { [ '苏南', '苏南' ] }

苏南大叔:JavaScript,如何理解具有天然去重特性的set数据类型? - keys-values
JavaScript,如何理解具有天然去重特性的set数据类型?(图6-5)

遍历.keys.values.entries

.keys().values().entries()都是迭代器类型的,而且鉴于在jsset类型里面,.keys.values数据完全一致,.entries()又是keyvalue的组合,所以对三者任何一个进行遍历都是一样的效果。

const _set = new Set(["sunan", "苏南"]);

console.log("===01===");
var _p1 = _set.keys();
for (i = 0; i < _set.size; i++) {
    console.log(_p1.next().value);
}

console.log("===02===");
var _p2 = _set.values();
let j = 0;
while (j < _set.size) {
    console.log(_p2.next().value);
    j++;
}

console.log("===03===");
const _p3 = _set.keys();
console.log(_p3.next().value);
console.log(_p3.next().value);

console.log("===04===");
let _p4 = _set.entries();
for (var i = 0; i < _set.size; i++) {
    let item = _p4.next().value;
    console.log(item[0], item[1]);
}

console.log("===05===");
_set.forEach((val, key) => {
    console.log(key, val);
});

苏南大叔:JavaScript,如何理解具有天然去重特性的set数据类型? - 遍历数据
JavaScript,如何理解具有天然去重特性的set数据类型?(图6-6)

相关链接

结束语

来点击看看更多的经验文字吧:

如果本文对您有帮助,或者节约了您的时间,欢迎打赏瓶饮料,建立下友谊关系。
本博客不欢迎:各种镜像采集行为。请尊重原创文章内容,转载请保留作者链接。

 【福利】 腾讯云最新爆款活动!1核2G云服务器首年50元!

 【源码】本文代码片段及相关软件,请点此获取更多信息

 【绝密】秘籍文章入口,仅传授于有缘之人   js