ECMAscript6 中Set数据结构

大家好混元霹雳手Ziksang又来了,给大家讲讲es6,Set这个新的数据结构

大年初三,先给大家拜个年,我知道我的拜方式错了!!红包即将打到你的支付宝中,请接收!

2017年的目标就是把ecmscript6所有的知识点全弄明白,我相信以后会基于ecmascript6的新特性肯定会出一些更牛B的框架,就像vue一样用了Object.defineProperty ecmascript5的新特性来进行数据劫持,所以我很期待

简单介绍一下吧

Set基本介绍

Set是ES6中数据结构中其中一个新的特性,我们看上去往往很像数组,但是他的每个成员都是唯一的,不会存在重复的值

Set也是一个构造函数,用来生成Set这个数据结构,我们可以看看他实例原型上有那些东西,简单看一下

在set原型上放了这么多方法,接下来我一一介绍一下吧,记住学习一定要学到根本!!!!

注意我的每一步代码都是自上而下有着关联的

add方法

let set = new Set()
let array = [1,"ziksang",3,3,true,5,5]
array.forEach(item => {
        set.add(item)
})
console.log(set)
// Set {1, "ziksang", 3, true, 5}

1.先new出set这个构造函数实列,我们存在set变量上
2再声明一个array这个数组,里面的数组成员有各种数据类型和重复的值
3.用Set原型上add方法把用es5中each方法把每个值添加到set成员里
4.打印出来是一个对象,里面相同类型相同值都会去掉,但是里面的整体结构和类组数对象一样,有着自己的长度

 for (let i of set) {
         console.log(i);
         console.log(typeof i)
}

以上我们再次用for of的方法也,同样也是es6的新特性,此时就可以把set对象里每一个值可以打印出来,里面的打印出的每一个数据类型也同样是我们array数组里定义的数据类型


上面代码通过add方法向Set结构加入成员,结果表明Set结构不会添加重复的值。
Set函数可以接受一个数组(或类似数组的对象)作为参数,用来初始化。

        function demo(){
            let set = new Set(arguments)
            console.log(set)
        }
        demo(1,2,4,4,5)
        //Set {1, 2, 4, 5}
        let set = new Set([1,2,4,4,5])
        console.log(set)
        //Set {1, 2, 4, 5}

1.Set函数里我们可以接受参数来作为初始化跟new Array[1,2,3,4]性质是一样的
2.第一个我在demo函数里让set函数接收了demo里arguments对象作为参数
3.第二个我直接在set函数里放入一个数组
4.两都console.log()打印出来的是一样的,同样不会包含同类型同样的值的成员

size方法

size方法是用来判断出,set里成员的个数

var items = new Set([1, 2, 3, 4, 5, 5, 5, 5]);
items.size // 5

1.虽然上面我定义了8个成员数量,但是最后个数只有5个,因为还是同样的不会把重复同类型同样的值算进去,只算一个

数组去重方法
在以前数我面试的时候别人一直接我数组去重怎么样,我现在只想回答他,看下面

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

1.声明一个数组
2.把数组作为set构造函数的初始化成员
3.再把set用[...set]来重新复制给array//简称拓展运算符...
4.扩展运算符(...)内部使用for...of循环,所以也可以用于Set结构。

关于类型转换,NaN,object的区别

在往set数据结构中添加值的值,并不会发生类型转换,4和“4”不同的数据类型不会发生转换,他的内部是用Same-value equality,也就是跟恒等差不多,但是NaN不一样很特殊

       console.log(NaN === NaN) //false
       const a = NaN;
       const b = NaN;
       const c = "1";
       const d = 1;
       let set = new Set()
       set.add(a)
       set.add(b)
       set.add(c)
       set.add(d)
       console.log(set) //Set {NaN, "1", 1}

1.如果单纯的比对NaN === NaN肯定是不相等的,但是在set数据结构中,里面的计算原理是把NaN看成相等的


对于两个对象来说,无是里面是否有值 ,可者有什么样的值都是不相等的,空对象也不相等

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

1.可以看出空对象是不相等的,所以它们被视为两个值。总个数依然是2个


Set实例的属性和方法,也就是Set构造函数上定义的方法和属性

Set结构的实例有以下属性。
Set.prototype.constructor:构造函数,默认就是Set函数。
Set.prototype.size:返回Set实例的成员总数。

Set实例的方法分为两大类:操作方法(用于操作数据)和遍历方法(用于遍历成员)。下面先介绍四个操作方法。

add(value):添加某个值,返回Set结构本身。
delete(value):删除某个值,返回一个布尔值,表示删除是否成功。
has(value):返回一个布尔值,表示该值是否为Set的成员。
clear():清除所有成员,没有返回值。

size和add我在前面已经讲过了,再少许提一下吧

        let set = new Set()
        set.add(3).add(2).add(2).add("ziksang");
        console.log(set)//set{3,2,ziksang}
        console.log(set.has(3)) //true
        console.log(set.delete(2))  //true
        console.log(set)   //set{3,ziksang}
        console.log(set.clear()) //undefined
        console.log(set) //set{}

1.我们new出Set构造函数的实列对象进行一个一个add进行添加,但是添加了两个同类型同样值 的2 !最后打印出来同样的一个会被去除
2.set.has()是进行对set数据结构中成员是否存在的判断
3.删除set数据结构中成员
4set.clear()是进行清除所有成员,set实列也因此成为了一个空对象


不同对比的例子,看看Object和Set两个数据结构判断方式不同

        let obj={
            name : "ziksang",
            age : 22
        }
        let set = new Set(["name",22])
        if(obj.name){
            console.log("在对象里有name这个健值")
        }
        if(set.has("name")){
            console.log("set数据结构中有name这个成员")
        }

提示

1.[阮一峰]用obj[somename]来判断是否对象里有这个健,打出来是undefined,以上修正了一下
2.判断set数据结构中是否有某个成员,用set.has()来判断


另外再介绍一下另一种数组去重方式

Array.from()是es6数组中新带的一个方法

        function demo(array){
            return Array.from(new Set(array))
        }
        let result = demo([1,1,2,2,3])
        console.log(result)//1,2,3

Array.from是什么鬼以后具体讲到es6数组我给大家讲讲,我现在只知其一,不知其二,讲不透彻的就不给大家讲


遍历操作
Set结构的实例有四个遍历方法,可以用于遍历成员。

keys():返回键名的遍历器
values():返回键值的遍历器
entries():返回键值对的遍历器
forEach():使用回调函数遍历每个成员
需要特别指出的是,Set的遍历顺序就是插入顺序。这个特性有时非常有用,比如使用Set保存一个回调函数列表,调用时就能保证按照添加顺序调用。

keys方法、values方法、entries方法返回的都是遍历器对象,因为set没有健名只有健值 ,所以健名和健值可以说是同一个值 ,keys和values返回的都是同一个值

       let set  = new Set([1,2,3,4])
       for(item of set.keys()){
           console.log(item) //1,2,3,4
       }
       for(item of set.values()){
           console.log(item) //1,2,3,4
       }
       for(item of set.entries()){
           console.log(item) //[1,1],[2,2],[3,3],[4,4]
           console.log(typeof item)//都是object对象
       }

1.keys,values,entries()返回的都是遍历器对象
2.entries返回的是健值对,因为为健和值都是一样的,所以里面两个也一样,但是返回出来是是一个对象,本值 上是一个类数组对象


Set结构的实例默认可遍历,它的默认遍历器生成函数就是它的values方法。第一个张图我也打印出prototype原型上的方法和属性里,里面的symbol.iterator里是values()所以也可以直接for of Set构造函数返回的实例

Set.prototype[Symbol.iterator] === Set.prototype.values
// true
       let set  = new Set([1,2,3,4])
       for(item of set){
           console.log(item) //1,2,3,4
       }

可以看出我们直接遍历SET实例和调用value()返回的遍历器对象是一样的


forEach()

Set结构的实例的forEach方法,用于对每个成员执行某种操作,没有返回值。

       let set  = new Set([1,2,3,4])
       set.forEach(function(value,key){
           console.log(value*key) //1,4,9,16
       })


上面代码说明了,对set实例里的健和值互乘,其实value和key都是一个值


数组的map和filter方法也可以用set上

       let set  = new Set([1,2,3])
       set = new Set([...set].map(item => item*2))
       console.log(set) //{2,4,6}
       set2 = new Set([...set].filter(item =>item>3))
       console.log(set2)//{4,6}

给大家解释一下用了那些关键方法
1[...set]把set实例进行转成数组再用map方法把线个值乘2给返回当作Set函数里的成员
2.filter方法也是同理,只是对数组 的值 进行筛选再返回


因此使用Set可以很容易地实现并集(Union)、交集(Intersect)和差集(Difference)。
1.并集Union

        let a = new Set([1,2,3,4,5])
        let b = new Set([1,2,3,6,7])
        let set = new Set([...a,...b])
        console.log(set) //1,2,3,4,5,6,7

上面把a,b里遍历出来在放入数组,再用set的特性进行去重

2.交集

        let a = new Set([1,2,3,4,5])
        let b = new Set([1,2,3,6,7])
        let intersect = new Set([...a].filter(x => b.has(x)))
        console.log(intersect) //{1,2,3}

上面是把a进行转化成数组用filter进行过滤,过滤的返回结果是b里面有的值

差集

        let a = new Set([1,2,3,4,5])
        let b = new Set([1,2,3,6,7])
        let intersect = new Set([...a].filter(x => !b.has(x)))
        console.log(intersect) //{4,5}

上面是把a进行转化成数组用filter进行过滤,过滤的返回结果是b里面没有的值

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

// 方法一
let set = new Set([1, 2, 3]);
set = new Set([...set].map(val => val * 2));
// set的值是2, 4, 6

// 方法二
let set = new Set([1, 2, 3]);
set = new Set(Array.from(set, val => val * 2));
// set的值是2, 4, 6

第一个方法本质上是把set重新进行赋值,先把原先的set里面的成为用[...set]化为数组再用map来进行重新操作再返回给set构造函数的成员

第二个方法等我弄懂了再告诉大家

这里我大部分都是按着阮一锋老师的书籍来进行分析,讲的好的我就记录下来,再用更白的话跟大家讲,有些不清楚说的模糊 的地方也更清楚的跟大家解释明白了,接下来我会把阮一锋老师 ES6所有的知识点都给大家搞明白,搞透彻

最后编辑于
©著作权归作者所有,转载或内容合作请联系作者
  • 序言:七十年代末,一起剥皮案震惊了整个滨河市,随后出现的几起案子,更是在滨河造成了极大的恐慌,老刑警刘岩,带你破解...
    沈念sama阅读 212,185评论 6 493
  • 序言:滨河连续发生了三起死亡事件,死亡现场离奇诡异,居然都是意外死亡,警方通过查阅死者的电脑和手机,发现死者居然都...
    沈念sama阅读 90,445评论 3 385
  • 文/潘晓璐 我一进店门,熙熙楼的掌柜王于贵愁眉苦脸地迎上来,“玉大人,你说我怎么就摊上这事。” “怎么了?”我有些...
    开封第一讲书人阅读 157,684评论 0 348
  • 文/不坏的土叔 我叫张陵,是天一观的道长。 经常有香客问我,道长,这世上最难降的妖魔是什么? 我笑而不...
    开封第一讲书人阅读 56,564评论 1 284
  • 正文 为了忘掉前任,我火速办了婚礼,结果婚礼上,老公的妹妹穿的比我还像新娘。我一直安慰自己,他们只是感情好,可当我...
    茶点故事阅读 65,681评论 6 386
  • 文/花漫 我一把揭开白布。 她就那样静静地躺着,像睡着了一般。 火红的嫁衣衬着肌肤如雪。 梳的纹丝不乱的头发上,一...
    开封第一讲书人阅读 49,874评论 1 290
  • 那天,我揣着相机与录音,去河边找鬼。 笑死,一个胖子当着我的面吹牛,可吹牛的内容都是我干的。 我是一名探鬼主播,决...
    沈念sama阅读 39,025评论 3 408
  • 文/苍兰香墨 我猛地睁开眼,长吁一口气:“原来是场噩梦啊……” “哼!你这毒妇竟也来了?” 一声冷哼从身侧响起,我...
    开封第一讲书人阅读 37,761评论 0 268
  • 序言:老挝万荣一对情侣失踪,失踪者是张志新(化名)和其女友刘颖,没想到半个月后,有当地人在树林里发现了一具尸体,经...
    沈念sama阅读 44,217评论 1 303
  • 正文 独居荒郊野岭守林人离奇死亡,尸身上长有42处带血的脓包…… 初始之章·张勋 以下内容为张勋视角 年9月15日...
    茶点故事阅读 36,545评论 2 327
  • 正文 我和宋清朗相恋三年,在试婚纱的时候发现自己被绿了。 大学时的朋友给我发了我未婚夫和他白月光在一起吃饭的照片。...
    茶点故事阅读 38,694评论 1 341
  • 序言:一个原本活蹦乱跳的男人离奇死亡,死状恐怖,灵堂内的尸体忽然破棺而出,到底是诈尸还是另有隐情,我是刑警宁泽,带...
    沈念sama阅读 34,351评论 4 332
  • 正文 年R本政府宣布,位于F岛的核电站,受9级特大地震影响,放射性物质发生泄漏。R本人自食恶果不足惜,却给世界环境...
    茶点故事阅读 39,988评论 3 315
  • 文/蒙蒙 一、第九天 我趴在偏房一处隐蔽的房顶上张望。 院中可真热闹,春花似锦、人声如沸。这庄子的主人今日做“春日...
    开封第一讲书人阅读 30,778评论 0 21
  • 文/苍兰香墨 我抬头看了看天上的太阳。三九已至,却和暖如春,着一层夹袄步出监牢的瞬间,已是汗流浃背。 一阵脚步声响...
    开封第一讲书人阅读 32,007评论 1 266
  • 我被黑心中介骗来泰国打工, 没想到刚下飞机就差点儿被人妖公主榨干…… 1. 我叫王不留,地道东北人。 一个月前我还...
    沈念sama阅读 46,427评论 2 360
  • 正文 我出身青楼,却偏偏与公主长得像,于是被迫代替她去往敌国和亲。 传闻我的和亲对象是个残疾皇子,可洞房花烛夜当晚...
    茶点故事阅读 43,580评论 2 349

推荐阅读更多精彩内容

  • 1.Set 基本用法 ES6提供了新的数据结构Set。它类似于数组,但是成员的值都是唯一的,没有重复的值。Set本...
    雨飞飞雨阅读 1,844评论 0 7
  • 一、快速配置安装zabbix3.2 1、本地zabbix源, 本地zabbix源配置 添加zabbix本地yum源...
    泡菜爱上WaSabi阅读 279评论 0 0
  • 无聊的人问你无聊时干什么,奈何你也是个无聊的人,你该怎么回答。有时候日子过着过着怎么就无聊了呢,看着其他人的快乐生...
    always1991阅读 318评论 0 0
  • 满天星星在闪烁,坠入深蓝的爱河。 那颗是你那颗我,爱河深深不可测。
    老槐树阅读 166评论 1 2