JS【详解】Set 集合 (含 Set 集合和 Array 数组的区别,Set 的 API,Set 与 Array 的性能对比,Set 的应用场景)

简介: JS【详解】Set 集合 (含 Set 集合和 Array 数组的区别,Set 的 API,Set 与 Array 的性能对比,Set 的应用场景)

Set 简介

ES6 新增了数据结构 Set,与数组类似,特征如下:

  • 无序
  • 元素不能重复

Set 集合和 Array 数组的区别

  • Set 元素不能重复,Array 元素可以重复
  • Set 是无序结构,操作很快,Array 是有序结构,操作很慢
  • Set 没有下标的概念,无法通过下标读取元素,Array 可以通过下标读取元素
  • 操作 Set 的 API 和 Array 不同

Set 的基本操作

大部分 API 和 Map 相同

new —— 创建 Set

// 创建空集合
const s = new Set();

// 创建时赋值
const colors = new Set(['red',white,'blue']);

也可传入数组创建set,但若数组内存在相同元素,则会去重!

let list = [1, 2, 3, 3];
let my_set = new Set(list);

console.log(my_set);
// 打印 Set(3) { 1, 2, 3 }

注意:引用类型的数据地址不同,即便看起来值一样,也属于不同的数据!

let list = [
  {
    name: "朝阳",
  },
  {
    name: "朝阳",
  },
];
let my_set = new Set(list);

console.log(my_set);
// Set(2) { { name: '朝阳' }, { name: '朝阳' } }

add —— 添加元素

my_set.add(1)

若原 set 中已存在新添加的元素,则什么都不会发生,也不会报错。

delete —— 删除元素

my_set.delete(1)

若原 set 中不存在要删除的元素,则什么都不会发生,也不会报错。

数组中基于元素的索引 splice() 来删除元素,速度很慢。

clear —— 清空元素

my_set.clear()

has—— 查询是否存在目标元素

返回 true / false

if (my_set.has("name")) {
}
  • 数组中使用 indexOf() 或 includes() 查询是否存在目标元素是比较慢。
  • 数组无法使用 indexOf() 或 includes() 来查找 NaN
let list = [NaN, 1, 3];
let index = list.indexOf(NaN);

console.log(index); // 得到 -1
  • Set 可以通过 has 查找 NaN
let my_set = new Set([NaN, 2, 3]);

console.log(my_set.has(NaN)); // 得到 true

size —— 获取元素的数量

类似数组的 .length

my_set.size

遍历 Set

// 没有 index
my_set.forEach((val) => {
  console.log(val);
});

Set 的性能(与 Array 对比)

  • Set用于搜索、删除和插入元素的方法的时间复杂度都只有 O(1),即数据的大小实际上与这些方法的运行时间无关。
  • 数组搜索的时间复杂度为 O(N),运行时间的增长速度与数据大小的增长速度相同。

Set 的应用场景

Vue3 数据响应式 reactive 和 effect 的源码中,大量使用了 Set

数组去重

仅适用于简单数组

let oldList = [1, 2, 3, 3];
let newList = Array.from(new Set(oldList)); // 得到 [1, 2, 3]

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

提升数组类数据的操作性能

因 Set 操作数据的性能比 Array 好,当需要对数据进行频繁操作,且对数据顺序无需求时,可考虑改用 Set 提升性能!

目录
相关文章
|
3月前
|
存储 NoSQL 关系型数据库
Redis 集合(Set)
10月更文挑战第17天
50 5
|
28天前
纸屑飘落生日蛋糕场景js+css3动画特效
纸屑飘落生日蛋糕CSS3动画特效是一款js+css3制作的全屏纸屑飘落,生日蛋糕点亮庆祝动画特效。
45 3
|
2月前
|
JavaScript 前端开发
js中的bind,call,apply方法的区别以及用法
JavaScript中,`bind`、`call`和`apply`均可改变函数的`this`指向并传递参数。其中,`bind`返回一个新函数,不立即执行;`call`和`apply`则立即执行,且`apply`的参数以数组形式传递。三者在改变`this`指向及传参上功能相似,但在执行时机和参数传递方式上有所区别。
32 1
|
2月前
set集合
HashSet(无序,唯一): 基于 HashMap 实现的,底层采用 HashMap 来保存元素。 LinkedHashSet: LinkedHashSet 是 HashSet 的子类,并且其内部是通过 LinkedHashMap 来实现的。 TreeSet(有序,唯一): 红黑树(自平衡的排序二叉树)。
|
2月前
|
存储 Java
判断一个元素是否在 Java 中的 Set 集合中
【10月更文挑战第30天】使用`contains()`方法可以方便快捷地判断一个元素是否在Java中的`Set`集合中,但对于自定义对象,需要注意重写`equals()`方法以确保正确的判断结果,同时根据具体的性能需求选择合适的`Set`实现类。
|
2月前
|
设计模式 JavaScript 前端开发
js中new和object.creat区别
【10月更文挑战第29天】`new` 关键字和 `Object.create()` 方法在创建对象的方式、原型链继承、属性初始化以及适用场景等方面都存在差异。在实际开发中,需要根据具体的需求和设计模式来选择合适的方法来创建对象。
|
2月前
|
存储 Java 开发者
在 Java 中,如何遍历一个 Set 集合?
【10月更文挑战第30天】开发者可以根据具体的需求和代码风格选择合适的遍历方式。增强for循环简洁直观,适用于大多数简单的遍历场景;迭代器则更加灵活,可在遍历过程中进行更多复杂的操作;而Lambda表达式和`forEach`方法则提供了一种更简洁的函数式编程风格的遍历方式。
|
2月前
|
Java 开发者
|
2月前
|
分布式计算 JavaScript 前端开发
在 JavaScript 中,哪些场景需要考虑精度控制?
【10月更文挑战第29天】JavaScript在上述各种场景中都需要根据具体的业务需求和数据特点,合理地进行精度控制,以确保计算结果的准确性和可靠性,从而为用户提供正确、稳定的服务和体验。
|
1月前
|
算法
你对Collection中Set、List、Map理解?
你对Collection中Set、List、Map理解?
61 18
你对Collection中Set、List、Map理解?