ES6学习笔记十一:Set和Map

本文深入探讨了ES6中的Set和Map数据结构。Set是不允许重复元素的集合,可用于数组和字符串去重,而Map是键值对的有序列表,键和值可以是任意类型。文章介绍了它们的创建、属性、方法、遍历方式以及与其他数据结构的转换,并展示了实际应用场景。

摘要生成于 C知道 ,由 DeepSeek-R1 满血版支持, 前往体验 >

前言

此系列文章用于记录小萌新的ES6的学习经历如有什么错误或者不好的地方请各位大佬多多指教


一、Set

1.1.Set概述

在Javascript中只有一个数组来表示集合数据,但是缺乏很多多表示的集合结构,如Python语言分为元组,列表,集合,字典,每一种都有不同集合的特点,在ES6中Javascript也对自己的集合类型进行了扩展添加了集合Set字典Map

1.2.Set的基本用法

  • Set的使用方法类似与数组,但是集合中不能存在相同的元素。
  • 再创建的时候使用new关键字直接对Set构造方法进行实例构造即可。

代码如下(示例):

{
  const s = new Set();
  [2, 3, 4, 5, 2, 2].forEach(x => s.add(x));
  for (let i of s) {
    console.log(i); // 2  3  4  5
  }

  let set = new Set([1, 2, 3, 4, 4]);
  console.log([...set]); //[ 1, 2, 3, 4 ]
}

Set构造函数可以接受一个数组(或具有Iterable接口的其他数据结构)作为参数,来初始化Set实例。

使用Set进行数组和字符串的去重操作

代码如下(示例):

{
   let items = new Set([1, 2, 3, 4, 5, 5, 5, 5]);
  console.log(...items); //1 2 3 4 5

  let str = "abbcddef";
  console.log([...new Set(str)].join("")); //abcdef
}

利用Set不能有重复元素的特点可以对具有迭代器的类型数据元素进行去重操作。(非常方便哦)

使用集合需要注意的地方
在于如果需要在集合中放入对象,他们并不会去重,因为在集合中各个元素进行比较的时候会使用内部比较机制

  • 向Set实例加入值时不会发生类型转换,因此5和’5’是不同的。
  • 利用算法“Same-value equality”来判断加入的值和已有的值是否相等,类似于Object.is( )方法,如果相等则不加入。
  • 两个对象总是不相等的(因为他们比较的是对象的引用)

代码如下(示例):

{
  let set = new Set();
  set.add({});
  set.add({});
  console.log(set.size); //2
  console.log(set); //Set(2) { {}, {} }

  let a = {};
  let b = a;
  set.add(a);
  set.add(b);
  console.log(set.size); //3
  console.log(set); //Set(3) { {}, {}, {} }
}

1.3.Set的属性与方法

属性

  • constructor,构造函数,默认就是Set函数。
  • size,返回Set实例的成员数量。(类似于数组的length)

操作方法

  • add(value),添加值,返回该Set实例的引用。
  • delete(value),删除值,返回一个布尔值,表示删除是否成功。
  • has(value),返回一个布尔值,表示该值是否是Set实例的成员。
  • clear( ),清除所有成员,没有返回值。

代码如下(示例):

{
  let set = new Set();
  set.add(1).add(2).add(2);
  console.log(set); //Set(2) { 1, 2 }

  console.log(set.has(2)); //true
  console.log(set.has(3)); //false

  set.delete(1);
  console.log(set); //Set(1) { 2 }

  set.clear();
  console.log(set); //Set(0) {}
}

遍历方法

  • keys( ),返回键名的遍历器。
  • values( ),返回键值的遍历器。
  • entries( ),返回键值对的遍历器。
  • forEach( ),使用回调函数遍历每个成员,没有返回值。

代码如下(示例):

{
   let set = new Set(["red", "green", "blue"]);
  for (let item of set.keys()) {
    console.log(item);  //red green blue
  }
  for (let item of set.values()) {
    console.log(item);  //red green blue
  }
  //Set结构实例的默认遍历器生成函数就是values()方法
  for (let item of set) {
    console.log(item); //red green blue
  }
  
  for (let item of set.entries()) {
    console.log(item); //[ 'red', 'red' ] [ 'green', 'green' ] [ 'blue', 'blue' ]
  }

  set.forEach(value => console.log(value.toUpperCase()));
  set.forEach((value, key, s) => {
    console.log(s.size); //3 3 3
    console.log(value); //red green blue
  });
}

需要注意的是

因为Set集合没有键,所以对于集合来说键(key)值(value)是一个东西。

1.4.Set的其他使用方法

Set集合可以先暂时转化成数组来借用数组的map()filter()方法。

代码如下(示例):

{
  let a = new Set([1, 2, 3]);
  let b = new Set([4, 3, 2]);
  //并集
  let union = new Set([...a], [...b]);
  console.log(union); //Set(3) { 1, 2, 3 }
  
  //交集
  let interect = new Set([...a].filter(x => b.has(x)));
  console.log(interect); //Set(2) { 2, 3 }
  
  //差集
  let diffs = new Set([...a].filter(x => !b.has(x)));
  console.log(diffs); //Set(1) { 1 }
}

二、Map

2.1.Map概述

Map类型是键值对的有序列表,而键和值都可以是任意类型。类似于Python的字典。

2.2.Map的基本用法

Map构造函数可以接收一个数组作为参数。

  • 该数组的成员是一组表示键值对的数组。
  • 不仅是数组,任何具有 Iterator 接口、且每个成员都是一个双元素的数组的数据结构都可以作为Map构造函数的参数。
  • Set和Map都可以用来生成新的 Map。

并且Map和Set的操作方法基本一致(除了添加一个元素和获取一个元素):

  • set(key, value),设置(添加)键值对。
  • get(key),通过key获取对应值。

类似Set的方法和属性

  • has(key)
  • delete(key)
  • clear( )
  • size

代码如下(示例):

{
  let map = new Map([
    ['name', 'zhang'],
    ['title', 'Author']
  ]);
  console.log(map.size); //2
  console.log(map.has('name')); //true
  console.log(map.get('name')); //zhang
  console.log(map.has('title')); //true
  console.log(map.get('title')); //Author

  let o = { p: 'Hello world' };
  map.set(o, 'content');
  console.log(map.size); //3
  console.log(map.get(o)); //content
  console.log(map.has(o)); //true
  console.log(map.delete(o)); //true
  console.log(map.has(o)); //false
  console.log(map.clear()); //undefined
  console.log(map); //Map(0) {}
}

需要注意的是:

如果Map的键是一个简单类型的值(数值,字符串,布尔值),只要两个值严格相等,Map就认为是同一个键。并且如果Map的键是一个对象如果这两个对象的引用是一样的则Map会把他们两个理解为同一个键

代码如下(示例):

{
  const mm = new Map();
  mm.set(["a"], 5);
  console.log(mm.get(["a"])); //undefined

  const k1 = {};
  const k2 = {};
  mm.set(k1, 100);
  mm.set(k2, 200);
  console.log(mm.get(k1), mm.get(k2)); //100 200
  
  mm.set(-0, 123);
  console.log(mm.get(+0)); //123

  mm.set(true, 1);
  mm.set("true", 2);
  console.log(mm.get(true)); //1
  console.log(mm.get("true")); //2

  mm.set(undefined, 3);
  mm.set(null, 4);
  console.log(mm.get(undefined)); //3
  console.log(mm.get(null)); //4

  mm.set(NaN, 111);
  console.log(mm.get(NaN)); //111
  console.log(mm);
  /*
  Map(9) {
  [ 'a' ] => 5,
  {} => 100,
  {} => 200,
  0 => 123,
  true => 1,
  'true' => 2,
  undefined => 3,
  null => 4,
  NaN => 111
  }
  */
}

2.3.Map的遍历方法

  • keys():返回键名的遍历器。
  • values():返回键值的遍历器。
  • entries():返回所有成员的遍历器。
  • forEach():遍历 Map 的所有成员。
  • Map 结构的默认遍历器接口(Symbol.iterator属性),就是entries方法。

代码如下(示例):

{
  const map = new Map([
    ["F", "no"],
    ["T", "yes"]
  ]);

  for (let [key, value] of map.entries()) {
    console.log(key, value); //F no T yes
  }
  for (let [key, value] of map) {
    console.log(key, value); //F no T yes
  }
}

和Set一样可以把Map暂时转换成数组来借用数组的map()和filter()方法。

2.4.Map与其他类型集合的转换的方法

代码如下(示例):

{
  //Map转换为数组
  const myMap = new Map().set(true, 7).set({ foo: 3 }, ["abc"]);
  let myArr = [...myMap];
  console.log(myArr);
}
{
  //数组转换为Map
  const myMap = new Map([
    [true, 7],
    [{ foo: 3 }, ["abc"]]
  ]);
  console.log(myMap);
}
{
    //Map转换为对象
    function strMapToObj(strMap) {
        let obj = Object.create(null);
        for (let [k, v] of strMap) {
            obj[k] = v;
        }
        return obj;
    }
    const myMap = new Map().set("yes", true).set("no", false);
    let obj = strMapToObj(myMap);
    console.log(obj, obj.yes, obj.no);
}
{
    //对象转换成Map
    function objToStrMap(obj) {
        let strMap = new Map();
        for (let [k, v] of Object.entries(obj)) {
            strMap.set(k, v);
        }
        return strMap;
    }
    let myMap = objToStrMap({ yes: true, no: false });
    console.log(myMap, myMap.get("yes"), myMap.get("no"));
}
{
    //Map转换成Json
    function strMapToJSON(strMap) {
        //先将Map转换为对象,在通过对象生成JSON。
        return JSON.stringify(strMapToObj(strMap));
    }
    let myMap = new Map().set("yes", true).set("no", false);
    let json1 = strMapToJSON(myMap);
    console.log(json1);
}
{
    //Json转Map
    function jsonToStrMap(jsonStr) {
        return objToStrMap(JSON.parse(jsonStr));
    }
    let theMap = jsonToStrMap('{"yes":true, "no": false}');
    console.log(theMap);
}

总结

本文主要讲述了ES6中的Set和Map方面的知识,如果又不好的地方希望大家多多提意见。

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值