Set数据结构

属性:

  • size:返回set实例的成员总数

    方法:

  • add():添加某个值,返回set本身

  • delete():删除某个值,返回一个布尔值,判断删除是否成功
  • has():返回一个布尔值,表示该值是否为set成员
  • clear():清除所有成员,没有返回值
  • keys():返回键名的遍历器
  • values():返回键值的遍历器
  • entries():返回键值对的遍历器
  • forEach():使用回调函数遍历每个成员

    一、实例剖析

    为了方便大家更好的了解和学习set,我在这里会将这些方法和属性进行分类整理和讲解

    1、set的基本用法

    1. <!DOCTYPE html>
    2. <html>
    3. <head>
    4. <meta charset="UTF-8">
    5. <title>数组去重</title>
    6. </head>
    7. <body>
    8. <script type="text/javascript">
    9. const set=new Set(); //创建set数据结构
    10. [1,1,2,3,4,5].forEach(x=>{
    11. set.add(x);
    12. })
    13. console.log(set); //1,2,3,4,5
    14. for(let i of set){
    15. console.log(i);
    16. }
    17. </script>
    18. </body>
    19. </html>

    set详解 - 图1
    可以看到向Set添加成员时,不会添加重复的值

    2、数组作为参数传入到set结构中

    1. <!DOCTYPE html>
    2. <html>
    3. <head>
    4. <meta charset="UTF-8">
    5. <title></title>
    6. </head>
    7. <body>
    8. <div></div>
    9. <div></div>
    10. <div></div>
    11. <div></div>
    12. <div></div>
    13. <script type="text/javascript">
    14. // const set=new Set([1,2,3]);
    15. // console.log(...set);//1,2,3,使用扩展运算符
    16. const set=new Set(document.querySelectorAll('div'));
    17. console.log(set.size);//5 size返回set实例的成员总数
    18. //如上代码相当于
    19. const item=new Set();
    20. document.querySelectorAll('div').forEach(x=>{
    21. item.add(x);
    22. })
    23. console.log(item);
    24. console.log(item.size);//5
    25. </script>
    26. </body>
    27. </html>

    3、set中添加的值不会发生类型转换

    1. <!DOCTYPE html>
    2. <html>
    3. <head>
    4. <meta charset="UTF-8">
    5. <title>向set中添加成员时,不会发生类型转换</title>
    6. </head>
    7. <body>
    8. <script type="text/javascript">
    9. let mySet=new Set();
    10. mySet.add(5);
    11. mySet.add('5');
    12. console.log(mySet);//5,'5'
    13. let set=new Set();
    14. let a=NaN;
    15. let b=NaN;
    16. set.add(a);
    17. set.add(b);
    18. console.log(set);//NaN
    19. </script>
    20. </body>
    21. </html>

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

    4、set中添加的对象总是不想等的

    1. <!DOCTYPE html>
    2. <html>
    3. <head>
    4. <meta charset="UTF-8">
    5. <title>向set中添加的对象总是不想等</title>
    6. </head>
    7. <body>
    8. <script type="text/javascript">
    9. let set=new Set();
    10. set.add({});//向set中添加一个空对象
    11. console.log(set.size);//1
    12. set.add({});//向set中添加另一个空对象
    13. console.log(set.size);//2
    14. </script>
    15. </body>
    16. </html>

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

    5、Array.from()方法

    Array.from()可以将set结构转为数组,这就提供了去除数组重复成员的另一种方法

    1. <!DOCTYPE html>
    2. <html>
    3. <head>
    4. <meta charset="UTF-8">
    5. <title>Array.from()方法</title>
    6. </head>
    7. <body>
    8. <script type="text/javascript">
    9. const items=new Set([1,2,3,4,5]);
    10. console.log(items);//1,2,3,4,5
    11. const array=Array.from(items);
    12. console.log(array);//1.2.3,4,5
    13. //Array.from()方法实现数组去重
    14. function dedupe(arr){
    15. return Array.from(new Set(arr))
    16. }
    17. console.log(dedupe([1,1,2,3]));//1,2,3
    18. </script>
    19. </body>
    20. </html>

    二、遍历的应用

    1、数组去重

    1. <!DOCTYPE html>
    2. <html>
    3. <head>
    4. <meta charset="UTF-8">
    5. <title>数组去重</title>
    6. </head>
    7. <body>
    8. <script type="text/javascript">
    9. let set=new Set(['red','blue','green']);
    10. let arr=[...set];
    11. console.log(arr);//red,blue,green
    12. //数组去重
    13. let arrs=[1,1,3,3,4,5,6];
    14. let unique=[...new Set(arrs)];
    15. console.log(unique);//1,3,4,5,6
    16. </script>
    17. </body>
    18. </html>

    2、间接使用数组的方法

    1. <!DOCTYPE html>
    2. <html>
    3. <head>
    4. <meta charset="UTF-8">
    5. <title>间接使用数组的方法</title>
    6. </head>
    7. <body>
    8. <script type="text/javascript">
    9. let set=new Set([1,2,3,4,5]);
    10. set=new Set([...set].map(x=>x*2));//使用数组的map方法
    11. console.log(set);//2,4,6,8,10
    12. let mySet=new Set([1,2,3,4,5]);
    13. mySet=new Set([...mySet].filter(x=>x%2==0));//使用数组的filter方法
    14. console.log(mySet);//2,4
    15. </script>
    16. </body>
    17. </html>

    3、实现并集,交集,差集

    1. <!DOCTYPE html>
    2. <html>
    3. <head>
    4. <meta charset="UTF-8">
    5. <title>实现并集,交集,差集</title>
    6. </head>
    7. <body>
    8. <script type="text/javascript">
    9. let a=new Set([1,2,3]);
    10. let b=new Set([4,3,2]);
    11. //并集
    12. let union=new Set([...a, ...b]);
    13. console.log(union);//1,2,3,4
    14. //交集
    15. let intersect=new Set([...a].filter(x=>b.has(x)));
    16. console.log(intersect);//2,3
    17. //差集
    18. let difference=new Set([...a].filter(x=>!b.has(x)));
    19. console.log(difference);//1
    20. </script>
    21. </body>
    22. </html>

    4、同步改变原来的 Set 结构

    如果想在遍历操作中,同步改变原来的 Set 结构,目前没有直接的方法,但有两种变通方法。一种是利用原 Set 结构映射出一个新的结构,然后赋值给原来的 Set 结构;另一种是利用Array.from方法。

    1. <!DOCTYPE html>
    2. <html>
    3. <head>
    4. <meta charset="UTF-8">
    5. <title>同步改变原来的 Set 结构</title>
    6. </head>
    7. <body>
    8. <script type="text/javascript">
    9. //方法一
    10. let set=new Set([1,2,3]);
    11. set=new Set([...set].map(val=>val*2));
    12. console.log(set);//2,4,6
    13. //方法二
    14. let mySet=new Set([1,2,3]);
    15. mySet=new Set(Array.from(mySet,val=>val*2));
    16. console.log(mySet);//2,4,6
    17. </script>
    18. </body>
    19. </html>

    三、set实例属性和方法

    1、size属性

    1. <!DOCTYPE html>
    2. <html>
    3. <head>
    4. <meta charset="UTF-8">
    5. <title>set中的size属性</title>
    6. </head>
    7. <body>
    8. <script type="text/javascript">
    9. const set=new Set();
    10. //向set中添加成员
    11. set.add(1);
    12. set.add(2);
    13. set.add(3);
    14. //链式方法
    15. set.add(4).add(5).add(6);
    16. console.log(set.size);//6
    17. </script>
    18. </body>
    19. </html>

    2、操作方法add()、delete()、has()、clear()

    1. <!DOCTYPE html>
    2. <html>
    3. <head>
    4. <meta charset="UTF-8">
    5. <title>set中的操作方法add()、delete()、has()、clear()</title>
    6. </head>
    7. <body>
    8. <script type="text/javascript">
    9. const set=new Set();
    10. //向set中添加成员
    11. set.add(1);
    12. set.add(2);
    13. set.add(3);
    14. //链式方法
    15. set.add(4).add(5).add(6);
    16. console.log(set.size);//6
    17. console.log(set.has(1));//true
    18. set.delete(1);
    19. console.log(set.has(1));//false
    20. set.clear();//清空全部set成员
    21. console.log(set.size);//0
    22. </script>
    23. </body>
    24. </html>

    3、遍历方法keys()、values()、entries()、forEach()

    注意:set的遍历顺序就是插入顺序,由于set没有键名,只有键值(或者说键名和键值是同一个值),所以keys()和values()方法的行为完全一致