小生愛

        /**
            ** Set 数据结构
            
            * set 是一种数据结构 类似数组 但成员的值都是唯一的 没有重复的
            
            * size : 返回Set实例的成员总数
            
            * add(value) : 添加某个值, 返回Set结构本身
            
            * delete(value) : 删除某个值返回true false
            
            * has(value1, value2, ... valueN) : 返回一个布尔值 表示该值是否为Set的成员 true false
            

            ** Map 数据结构 
            
            ** Map的键实际上是跟内存地址绑定的 只要内存地址不一样 就视为两个键 
            
            * set(key, value) : 添加一个键值
            
            * delete(key) : 删除一个键
            
            * has(keys) : 查找一个键
            
            * get(keys) : 获取某个键值
            
            * size : 返回map结构的成员总数 
            
            * clear() : 清除所有返回值
            
            * values() : 返回value集合
            
            * keys() : 返回key集合 
            
        */

        
        var s = new Set();

        // add 添加某个值 返回Set结构本身
        // 返回 Set {2, 3, 5, 4}
        [2, 3, 5, 4, 5, 2, 2].map(x => s.add(x));




        // 接受一个数组参数
        let set = new Set([1, 2, 3, 4, 4]);
        // 输出1, 2, 3, 4
        console.log(...set);




        let set = new Set([1, 2, 3, 4, 5, 5, 5]);

        // 返回实例的成员总数 5 
        // 实例化set时 已经去掉了重复的值
        console.log(set.size);




        // 2个对象总是不相等的
        let set = new Set();
        let o1 = {a:1, b:2};
        let o2 = {a:1, b:2};
        
        set.add(o1);
        set.add(o2);
        
        // Object {a: 1, b: 2} Object {a: 1, b: 2}
        console.log( set );




        // delete 删除某个值 返回true false
        let set = new Set([2, 2, 3]);

        console.log( set.delete(2), set );




        // has(value) 只能搜索一个值
        let set = new Set([2, 2, 3]);

        console.log( set.has(2) );




        let set = new Set([1, 1, 3]);

        // Array.from 将set转成数组
        console.log( Array.from(set) );





        let a = new Set([1, 2, 3]);
        let b = new Set([4, 3, 2]);
        
        // 并集
        let union = new Set([...a, ...b]);
        // 交集
        let intersect = new Set([...a].filter(x => b.has(x)));
        // 差集
        let difference = new Set( [...a].filter( x => !b.has(x) ) );
        



        let a = new Set([1, 2, 3, 3])
        let value = [...a].map(x => x * 2)
        // 如果想在遍历操作中 同步改变原来的Set结构
        // 映射一个新set 然后赋值给 a
        a = new Set(value)


        
        
        /**
             Map
        */
        let m = new Map();
        let o = {p : 'Hello'};
        // 添加值
        m.set(o, 'content');
        // 添加另外一个键和值
        m.set('o', 'abc');
        // 删除键值
        m.delete(o);
        // 查找某个键值是否存在
        // 只能查找一个值
        m.has('o');
        // 获取某个键值
        m.get(o);




        // 只有对同一个对象的引用 Map结构才将其视为同一个键
        m.set({p : 'Hello'}, 'content');
        m.set({p : 'Hello'}, 'abc');
        // 输出undefined
        console.log(m.get({p : 'Hello'}));




        // 用DOM节点保存值 对同一个节点可以取值
        let el = document.querySelectorAll('div');
        let map = new Map();
        el.forEach((a, b, c) => map.set(a, '小花'));
        c( map.get(document.querySelector('div')) );




        // 数组做参数 第一个值变成key 第二个变成value
        let arr = [
            ['name', '张三'],
            ['title', 'Author']
        ];
        let map = new Map(arr);
        // Map {"name" => "张三", "title" => "Author"}
        // name title 变成了键值
        c(map);




        // 如果二维数组每个里面有2个以上的值 后面的都忽略
        let map = new Map([
            ['name', '小1', '2'],
            ['title', '213', '3']
        ])

        let name = 'name'

        log( map )
        log( map.size )
        log( map.has('name') )
        log( map.get('name') )
        log( map.has('title') )
        log( map.get('title') ) 




        // 只有对同一个对象的引用 Map结构才将其视为同一个键
        let map = new Map()

        map.set(['a'], '小花')
        map.get(['a'])
        



        // 如果值是对象 就算值相同 作为键 也是2个不同的键 因为内存地址不同
        let map = new Map()
        let k1 = ['a']
        let k2 = ['a']

        map.set(k1, 111)
        map.set(k2, 222)

        log(map.get(k1))
        log(map.get(k2))


        // 如果值是非对象类型 并且值相同 作为键 视为是相同键 后面的会覆盖 前面的值
        let map2 = new Map()
        let v1 = 'a'
        let v2 = 'a'

        map2.set(v1, 333)
        map2.set(v2, 444)

        log(map2.get(v1))
        log(map2.get(v2))




        let map = new Map();
        map.set('foo', true);
        map.set('bar', false); 
        // 清除所有成员 没有返回值
        map.clear();  
        // 0  
        map.size;




        let map = new Map().set('a', 1).set('b', 2);
        // MapIterator {1, 2}
        map.values();
        // MapIterator {a, b}
        map.keys();




        // 遍历 Map 的方法
        let m = new Map()

        m.set('a', 1)
        m.set({a: 1}, 2)

        m.forEach(x => log(x))

        for (let [k, v] of m) {
            log(k, v)
        }




        let map = new Map([
            ['F', 'no'],
            ['T', 'yes']
        ])
        // MapIterator {"F", "T"}
        map.keys()
        // MapIterator {"no", "yes"}
        map.values()
        for (let [key, value] of map) {
            log(key, value)
        }
        for (let key of map.keys()) {
            log(key)
        }
        for (let value of map.values()) {
            log(value)
        }
        map.forEach((x, i, arr) => log(x, i, arr))




        // map 转数组 map filter 遍历
        let map = new Map([
            ['1', '小花'],
            ['2', '小蓝'],
            ['3', '小白']
        ])

        // ["1", "2", "3"]
        [...map.keys()]

        // ["小花", "小蓝", "小白"]
        [...map.values()]

        // 原始二位数组
        [...map]

        // Map {"1" => "小花", "2" => "小蓝"}
        let map1 = new Map(
            // 过滤
            [...map].filter( ([k, v]) => k < 3 )
        )

        // Map {"1" => "小花-田田", "2" => "小蓝-田田", "3" => "小白-田田"}
        let map2 = new Map(
            [...map].map( ([k, v]) => [k, `${v}-田田`] )
        )