Set集合类型

ECMAScript 6 新增Set集合类型,为这门语言带来集合数据结构。Set在很多方面都像加强的Map,这是因为它们的大多数API和行为都是共有的。

6.6.1 基本API

  1. 使用new关键字和Set构造函数可以创建一个空集合。如果想在创建的同时初始化实例,可以给Set构造函数传入一个可迭代对象,其中需要包含插入到集合实例中的元素。

    const m = new Set();
    // 使用数组初始化集合
    const sl = new Set(
      [
        "val1","val2","val3"
      ]
    )
    console.log(sl.size); // 3
    
    // 使用自定义迭代器初始化集合
    const s2 = new Set({
      [Symbol.iterator]: function* () {
        yield "val1";
        yield "val2";
        yield "val3"
      }
    })
    console.log(s2); // Set { 'val1', 'val2', 'val3' }
    
  2. 初始化之后,可以使用add()增加值,使用has()查询,通过size取得元素数量,以及使用delete()和clear()删除元素。

  3. add()返回集合的实例,所以可以将多个添加操作连接起来,包括初始化。

    const s = new Set();
    console.log(s.has("Matt")); // false
    console.log(s.size); // 0
    
    s.add("Matt").add("frisbie");
    console.log(s.has("Matt")); // true
    console.log(s.size); // 2
    
    s.delete("Matt"); 
    console.log(s.has("Matt")); // false
    console.log(s.has("frisbie")); // true
    console.log(s.size); // 1
    
    s.clear();
    
    console.log(s.has("Matt")); // false
    console.log(s.has("frisbie")); // false
    console.log(s); // set {}
    
    const ss = new Set().add("vall");
    ss.add("val2").add("val3");
    console.log(ss); // Set { 'vall', 'val2', 'val3' }
    
  4. Map类似,set可以包含任何JavaScript数据类型作为值,集合也使用SameValueZero操作,基本上相当于使用严格对象相等的标准来检查值的匹配性。与严格相等一样,用作值的对象和其他集合类型在自己的内容或属性被修改时也不会改变。

  5. add()和delete()操作是幂等的,delete()返回一个布尔值,表示集合中是否存在要删除的值。

    const s = new Set();
    const functionVal = function () { };
    const symbolVal = Symbol();
    const objectVal = new Object();
    
    s.add(functionVal).add(symbolVal).add(objectVal);
    console.log(s.has(functionVal)); // true
    console.log(s.has(objectVal)); // true
    console.log(s);   // Set { [Function: functionVal], Symbol(), {} }
    
    // 检查意味着独立的实例不会冲突
    console.log(s.has(function () { })); // false
    
    const a = new Set();
    const objVal = {};
    const arrVal = [];
    a.add(objVal);
    a.add(arrVal);
    
    objVal.bar = "bar";
    arrVal.push("bar");
    
    console.log(a.has(objVal)); // true
    console.log(a.has(arrVal)); // true
    console.log(a); // Set { { bar: 'bar' }, [ 'bar' ] }
    
    const x = new Set();
    x.add('foo');
    console.log(x.size); // 1
    x.add('foo');
    console.log(x.size); // 1
    
    console.log(x.delete('foo')); // true
    console.log(x.delete('foo')); // false
    

6.6.2顺序与迭代

  1. Set会维护值插入时的顺序,因此支持按顺序迭代。集合实例可以提供一个迭代器(Iterator),能以插入顺序生成集合内容。可能通过values()方法及其别名方法keys(),或者Symbol.iterator属性,它引用values()取得这个迭代器。

  2. 因为values()是默认迭代器,所以可以直接对集合实例使用扩展操作,把集合转为数组,集合的entries()方法返回一个迭代器,可以按照插入顺序产生包含两个元素的数组,这两个元素是集合中每个值的重复出现。

    const s = new Set(["val1","val2","val3"]);
    console.log(s.values === s[Symbol.iterator]); // true
    console.log(s.keys === s[Symbol.iterator]); // true
    
    for (let value of s.values()) {
      console.log(value);
    }
    // val1
    // val2
    // val3
    for (let value of s[Symbol.iterator]()) {
      console.log(value);
    }
    // val1
    // val2
    // val3
    console.log([...s]); // [ 'val1', 'val2', 'val3' ]
    
    for (let pair of s.entries()) {
      console.log(pair);
    }
    // ['val1', 'val1']
    // ['val2', 'val2']
    // ['val3', 'val3']
    
  3. 如果不使用迭代器,而是使用回调方式,则可以调用集合的forEach()方法并传入回调,依次迭代每个键值对。传入的回调接收可选的第二个参数,这个参数用于重写回调内部this的值。

    const s = new Set(["val1", "val2", "val3"]);
    s.forEach((val, dupVal) => console.log(`${val}->${dupVal}`))
    // val1 - > val1
    // val2 - > val2
    // val3 - > val3
    
    const s1 = new Set(["val1"]);
    // 字符串原始值作为值不会被修改
    for (let value of s1.values()) {
      value = "newval";
      console.log(value); // newval
      console.log(s1.has("val1")); // true
    }
    const valObj = {id:1} 
    const s2 = new Set([valObj]);
    
    // 修改值对象的属性,但对象仍然存在于集合中
    for (let value of s2.values()) {
      value.id = "newVal";
      console.log(value); // { id: 'newVal' }
      console.log(s2.has(valObj)); // true
    }
    console.log(valObj); // { id: 'newVal' }
    

6.6.3定义正式集合操作

目前不太理解,故先不上任何描述文字和代码了。

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值