JavaScript中的Set和Map集合

除了传统的数组,JavaScript中还可以使用Set和Map等集合类型,本文将介绍相关应用。

Set

Set集合的元素不允许重复,判断元素是否存在时会采用全等,即"123"和123视为两个不同的元素。使用构造函数创建Set对象时,没有参数时会创建空对象;将数组作为参数时,数组元素就是Set集合的元素,下面的代码演示了Set对象的创建。

JavaScript
<script>
    let s1 = new Set();
    let arr = [1, 2, 3];
    let s2 = new Set(arr);
    alert(s1.size);  // 0
    alert(s2.size);  // 3
</script>

代码中,s1对象为没有元素的空集合,s2对象则包含了arr数组的三个元素,最后使用Set对象的size属性显示了两个集合的元素数量。

下面是Set集合对象的常用方法。

  • has()方法,判断元素是否存在,存在时返回true,不存在返回false。
  • add()方法,添加一个元素。
  • delete()方法,删除一个元素。当元素存在并删除时返回true,否则返回false。
  • clear()方法,删除所有元素。

Set对象的元素并不能像数组那样使用索引访问,但可以通过for...of逐一访问并处理元素数据,如下面的代码。

JavaScript
<script>
    let s1 = new Set();
    s1.add(1);
    s1.add(2);
    s1.add(3);
    for (let e of s1) {
        alert(e);
    }
</script>

执行代码会逐一显示1、2、3。

Set对象中的add()方法定义为可链式调用的方法,其返回值是当前Set对象,所以,add()方法可以连续调用,如下面的代码。

JavaScript
<script>
    let s1 = new Set();
    s1.add(1).add(2).add(3);
    for (let e of s1) {
        alert(e);
    }
</script>

此外,Set对象也可以使用forEach()方法逐一处理元素,如下面的代码会计算Set对象中所有元素的和。

JavaScript
<script>
    let s1 = new Set();
    s1.add(1).add(2).add(3).add(4).add(5).add(6);
    let sum = 0;
    s1.forEach(e => {
        sum += e;
    });
    alert(sum);  // 21
</script>

执行代码会显示1、2、3、4、5、6相加的和21。

Set是可迭代对象,需要将Set对象转换为数组时,可以将Set对象作为Array.from()方法的参数,如下面的代码。

JavaScript
<script>
    let s1 = new Set();
    s1.add(1).add(2).add(3);
    let arr = Array.from(s1);
    alert(arr);  // 1,2,3
</script>

Map

Map对象的数据项为“键/值”对应结构,其中,“键(key)”可以看作数据的名称;在Map对象中“键”是不能重复的。

使用构造函数创建Map对象时,没有参数时创建为空对象,也可以通过“[[key1,value1],[key2,value2],...]”格式设置集合数据。下面的代码演示了Map对象的创建。

JavaScript
<script>
    let m1 = new Map();
    let m2 = new Map([["name", "Tom"], ["age", 25], ["sex", "男"]]);
    alert(m1.size); // 0
    alert(m2.get("name"));  // Tom
</script>

m1对象定义为没有数据的空集合,size属性值为0;m2对象定义有三个数据项,第二个alert()函数中使用对象的get()方法读取了“name”的数据,显示为Tom。

下面是Map对象常用的属性和方法。

  • size属性,返回数据项数量。
  • has(key)方法,判断键(key)是否存在,存在返回true,不存在返回false。
  • set(key,value)方法,添加或修改数据。当键(key)不存在时,添加key和value组成的新数据项;当键(key)存在时,会修改数据为value。set()方法也是可以链式操作的方法,可连续添加数据项。
  • get(key)方法,通过键(key)读取数据,key不存在时返回undefined。
  • delete(key)方法,当键(key)存在并成功删除数据项时返回true,否则返回false。
  • clear()方法,清除所有数据项。
  • keys()方法,返回所有的键(key)组成的可迭代对象。
  • values()方法,返回所有的数据组成的可迭代对象。

下面的代码演示了Map对象的基本应用。

JavaScript
<script>
    let m1 = new Map();
    m1.set("name", "Tom").set("age", 25).set("sex", "男");
    alert(m1.has("phone"));  // false
    m1.set("phone", "12345678910");
    alert(m1.has("phone")); // true
    alert(m1.delete("address")); // false
    alert(m1.delete("phone")); // true
</script>

下面的代码会通过for...of语句访问Map对象的所有数据项目。

JavaScript
<script>
    let m1 = new Map();
    m1.set("name", "Tom").set("age", 25).set("sex", "男");
    for (let [key, value] of m1) {
        alert(`${key}:${value}`);
    }
</script>

执行代码会依次显示name:Tom、age:25、sex:男。

Map对象的forEach()方法同样可以依次访问和处理所有的数据项,如下面的代码。

JavaScript
<script>
    let m1 = new Map();
    m1.set("name", "Tom").set("age", 25).set("sex", "男");
    m1.forEach(function (value, key) {
        alert(`${key}:${value}`);
    });
</script>

执行代码同样会显示name:Tom、age:25、sex:男。

此外,在传统的JavaScript代码中也可以定义Map结构的数据,其格式如下:

JavaScript
{key1:value1, key2:value2, ...}

下面的代码演示了Map结构数据的基本应用。

JavaScript
<script>
    let m1 = { "name": "Tom", "age": 25, "sex": "男" };
    alert(m1["name"]);  // Tom
    alert(m1.age);  // 25
    alert(m1.sex);  // 男
</script>

需要将Map结构数据转换为Map对象时,可以通过Object.entries()方法转换,如下面的代码。

JavaScript
<script>
    let data = { "name": "Tom", "age": 25, "sex": "男" };
    let m1 = new Map(Object.entries(data));
    alert(m1.get("name"));  // Tom
    alert(m1.get("age"));  // 25
    alert(m1.get("sex"));  // 男
</script>

将Map对象的数据转换为Map结构数据时可以参考如下代码。

JavaScript
<script>
    let m1 = new Map([["name", "Tom"], ["age", 25], ["sex", "男"]]);
    let m2 = {};
    m1.forEach(function (value, key) {
        m2[key] = value;
    });
    //
    alert(m2.name);  // Tom
    alert(m2.age);  // 25
    alert(m2.sex);  // 男
</script>

代码中,m1定义为Map对象,m2定义为空的Map结构;然后,通过m1对象的forEach()方法访问所有的键、值,并通过“m2[键]=值”的格式将数据添加到m2对象中。