• es6-Set与Map


    se5中的set与map

    在est5中开发者使用对象属性来模拟。set多用于检查键的存在,map多用于提取数据。

    {
        let set = Object.create(null)
        set.foo = true;
        //检查属性是否存在
        if (set.foo) {
            //其他操作
        }
    
        let map = Object.create(null);
        map.foo = '一个值';
        let val = map.foo;
    
        console.log('map-->:', val); //map-->:一个值'
    }

    在简单情况下将对象作为map和set来使用都是可行的,但是一旦接触到对象属性的局限性,此方式就会遇到更多的麻烦。

    {
        let map1 = Object.create(null),
            key1 = {},
            key2 = {};
    
        map1[key1] = 'foo';
        console.log('key2-->:', map1[key2]);
    
        let map2 = Object.create(null);
        map2.count = 1;
        //是想检查count的存在,还是非零值?
        if (map2.count) {
            //...
        }
    }

    map1[key1]和map1[key2]引用了同一个值。由于对象属性只能是string,又因为对象默认的string表达形式是'[object object]'。导致key1和key2被转换为同一个字符串。map2中count的用法存在歧义。该if语句内的代码都会被执行因为1被隐式转换为true。然而count的值为0则会被隐式转为false。在大型应用中这类问题都是难以确认,难以调试的。这也是新增set和map类型的原因。set类型是一种无重复值的有序列表。set允许对它包含的数进行快速访问,从而更有效的追踪各种离散值。

    创建set类型

    使用new set()来创建。调用add()方法向集合中添加元素,访问集合的size属性获取集合数量。

    {
        let set = new Set();
    
        set.add(5);
        set.add('5');
        console.log('typeof set-->:', typeof set)
        console.log('set-->:', set)
        console.log('size-->:', set.size)
    }

    set不会使用强制类型转换来判断值是否重复,这意味着set可以同时包含number(5)和string(5),唯一的例外-0和+0在set中被判定是相等的,如果向set集合中添加多个对象,则他们之间彼此独立。

    {
        let set = new Set();
        let key1 = {};
        let key2 = {};
    
        set.add(key1);
        set.add(key2);
        console.log('typeof setobject-->:', typeof set)
        console.log('setobject-->:', set)
        console.log('size-->:', set.size)
    }

    由于key1和key2不会被转换为字符串,所以在set内部是不同的项,如果他们被转化为字符串,那么都会等于"[object object]",如果多次调用add()并传入相同的值作为参数。那么后续的调用会被忽略。

    {
        let set = new Set();
    
        set.add(5);
        set.add('5');
        set.add(5);
        console.log('typeof set-->:', typeof set)
        console.log('set-->:', set)
        console.log('size-->:', set.size)
    }

    第二次重复传入numner(5)并不会被添加到set集合中,那么size的属性值还是为2。也可以使用数组来初始化set集合。集合同样会过滤重复的值。

    {
        let set = new Set([1, 2, 3, 4, 5, 5, 5, 5, 5, 5]);
        console.log('size-->:', set.size);
    }

    通过has()可以检测set集合中是否存在某个值。

    {
        let set = new Set();
    
        set.add(5);
        set.add('6');
        console.log('set has-->:', set.has(6));
        console.log('set has-->:', set.has('6'))
        console.log('set has-->:', set.has(5))
        console.log('set has-->:', set.has('5'))
    }

    set集合中相同的number和sting并不会返回true。调用delete()方法可以移除set中的某一个值,调用clear()方法可以移除所有值。

    {
        let set = new Set();
    
        set.add(5);
        set.add('6');
        console.log('set has-->:', set.has('6'));
        set.delete('6')
        console.log('set has-->:', set.has('6'))
        console.log('size-->:', set.size)
        set.clear();
        console.log('size-->:', set.size)
    }

    set集合简单易用,可以有效的跟踪多个独立有序的值。

    set的forEach

    set集合和数组的forEach类似,运行机制也比较类似。forEach()方法的回调接收3个参数:
    1.集合中索引的位置。
    2.被遍历参数的值
    3.集合本身

    {
        let set = new Set(['a', 'b', 'c', 'd', 'e']);
        set.forEach((k, val, owner) => {
            console.log('set-forEach-k-->:', k);
            console.log('set-forEach-val-->:', val);
            console.log('set-forEach-owner-->:', owner);
        })
    }

    将set转换为数组

    将数组转换为set集合的过程很简单,需要给set集合传入数组即可。将集合转回数组,只需要使用展开运算符即可。

    {
        let arr = [1, 2, 3, 4, 5, 5, 5, 5, 5, 5];
        let set = new Set(arr);
        let newArr = [...set];
        //ps: 代码行数太多可以压缩下
        let newArr2 = [...new Set([1, 2, 3, 4, 5, 5, 5, 5, 5, 5])];
        console.log(newArr, newArr2)
    }

    创建map类型

    map类型是键值对的有序列表,键和值都可以是任意类型,可以调用set()方法传递一个键和一个关联的值,来给马屁添加项;此后使用键名来调用get()方法获取对应的值。

    {
        let map = new Map();
        map.set('title', 'es6');
        map.set('year', 2016);
    
        console.log('map-title-->', map.get('title'))
        console.log('map-year-->', map.get('year'))
    }

    map的方法

    map和set共享了几个方法。以下的方法和属性map和set上都存在:
    1.forEach(val, k, owner): 遍历map
    2.has(key):判断指定的键值是否存在
    3.delete(key):移除map中键以及对应的值
    4.clear():移除map中所有的键和值
    5.size:指明包含多个键值对。

    {
        let map = new Map();
        map.set('title', 'es6');
        map.set('year', 2016);
    
        map.forEach((val, k, owner) => {
            console.log('map-forEach-k-->:', k);
            console.log('map-forEach-val-->:', val);
            console.log('map-forEach-owner-->:', owner);
        })
        console.log('map-size-->:', map.size);
    
        console.log('map-has-->:', map.has('title'));
    
        map.delete('title');
        console.log('map-->:', map);
    
        map.clear();
        console.log('map-->:', map);
    }

    小结

    es6正式将set与map引入。在此之前往往使用对象来模拟,但是由于与对象属性有关的限制,这么做会经常遇到问题。
    这里并没有弱引用weakset和weakmap,有这方面需要的可以自己去查阅

  • 相关阅读:
    队列课下作业
    20162305 2017-2018-1 《程序设计与数据结构》第6周学习总结
    20162305 2017-2018-1 《程序设计与数据结构》第5周学习总结
    线性结构 实验报告 20162305
    算法复杂度-实验博客
    2017-2018-1 《程序设计与数据结构》第3周学习总结
    20162305 2017-2018-1 《程序设计与数据结构》第2周学习总结
    20162316刘诚昊 课下排序测试
    20162316刘诚昊 17年10月9日测验“排序课堂测试”
    20162316刘诚昊 第五周学习总结
  • 原文地址:https://www.cnblogs.com/10manongit/p/12796488.html
Copyright © 2020-2023  润新知