ES6入門之Set和Map(七)

前言

當咱們須要存儲一些數據的時候,首先想到的是定義一個變量用來存儲,以後咱們可能學了數組,發現數組比變量能夠存儲更多的數據,接着可能有其它的存儲數據的方法等等,然而我今天須要介紹的是在ES6中比較常見使用的數據類型結構,Set和Map。

Set數據結構

1.Set簡介

  • set中成員的值都是惟一的,沒有重複的值

  • 向set中添加成員時,不會發生類型轉換

  • 向set中添加的對象老是不想等

2.經常使用的屬性和方法

  • size:返回set實例的成員總數

  • add():添加某個值,返回set自己

  • delete():刪除某個值,返回一個布爾值,判斷刪除是否成功

  • has():返回一個布爾值,表示該值是否爲set成員

  • clear():清除全部成員,沒有返回值

  • keys():返回鍵名的遍歷器

  • values():返回鍵值的遍歷器

  • entries():返回鍵值對的遍歷器

  • forEach():使用回調函數遍歷每一個成員

3.實例剖析

爲了方便你們更好的瞭解和學習set,我在這裏會將這些方法和屬性進行分類整理和講解javascript

(1):set的基本用法

<!DOCTYPE html>
<html>
    <head>
        <meta charset="UTF-8">
        <title>數組去重</title>
    </head>
    <body>
        <script type="text/javascript">
            const set=new Set();    //建立set數據結構
            [1,1,2,3,4,5].forEach(x=>{
                set.add(x);
            })
            console.log(set);    //1,2,3,4,5
            for(let i of set){
                console.log(i);
            }
        </script>
    </body>
</html>

 能夠看到向Set添加成員時,不會添加劇復的值html

(2):數組做爲參數傳入到set結構中

<!DOCTYPE html>
<html>
    <head>
        <meta charset="UTF-8">
        <title></title>
    </head>
    <body>
        <div></div>
        <div></div>
        <div></div>
        <div></div>
        <div></div>
        <script type="text/javascript">
//            const set=new Set([1,2,3]);
//            console.log(...set);//1,2,3,使用擴展運算符
            
            const set=new Set(document.querySelectorAll('div'));
            console.log(set.size);//5 size返回set實例的成員總數
            //如上代碼至關於
            const item=new Set();
            document.querySelectorAll('div').forEach(x=>{
                item.add(x);
            })
            console.log(item);
            console.log(item.size);//5
        </script>
    </body>
</html>

(3).set中添加的值不會發生類型轉換

<!DOCTYPE html>
<html>
    <head>
        <meta charset="UTF-8">
        <title>向set中添加成員時,不會發生類型轉換</title>
    </head>
    <body>
        <script type="text/javascript">
            let mySet=new Set();
            mySet.add(5);
            mySet.add('5');
            console.log(mySet);//5,'5'
            let set=new Set();
            let a=NaN;
            let b=NaN;
            set.add(a);
            set.add(b);
            console.log(set);//NaN
        </script>
    </body>
</html>

向 Set 加入值的時候,不會發生類型轉換,因此5"5"是兩個不一樣的值。Set 內部判斷兩個值是否不一樣,使用的算法叫作「Same-value-zero equality」,它相似於精確相等運算符(===),主要的區別是向 Set 加入值時認爲NaN等於自身,而精確相等運算符認爲NaN不等於自身。java

(4).set中添加的對象老是不想等的

<!DOCTYPE html>
<html>
    <head>
        <meta charset="UTF-8">
        <title>向set中添加的對象老是不想等</title>
    </head>
    <body>
        <script type="text/javascript">
            let set=new Set();
            set.add({});//向set中添加一個空對象
            console.log(set.size);//1
            set.add({});//向set中添加另外一個空對象
            console.log(set.size);//2
        </script>
    </body>
</html>

因爲兩個空對象不相等,因此它們被視爲兩個值es6

(5):Array.from()方法

Array.from()能夠將set結構轉爲數組,這就提供了去除數組重複成員的另外一種方法算法

<!DOCTYPE html>
<html>
    <head>
        <meta charset="UTF-8">
        <title>Array.from()方法</title>
    </head>
    <body>
        <script type="text/javascript">
            const items=new Set([1,2,3,4,5]);
            console.log(items);//1,2,3,4,5
            const array=Array.from(items);
            console.log(array);//1.2.3,4,5
            //Array.from()方法實現數組去重
            function dedupe(arr){
                return Array.from(new Set(arr))
            }
            console.log(dedupe([1,1,2,3]));//1,2,3
        </script>
    </body>
</html>

4.遍歷的應用

(1):數組去重

<!DOCTYPE html>
<html>
    <head>
        <meta charset="UTF-8">
        <title>數組去重</title>
    </head>
    <body>
        <script type="text/javascript">
            let set=new Set(['red','blue','green']);
            let arr=[...set];
            console.log(arr);//red,blue,green
            //數組去重
            let arrs=[1,1,3,3,4,5,6];
            let unique=[...new Set(arrs)];
            console.log(unique);//1,3,4,5,6
        </script>
    </body>
</html>

(2):間接使用數組的方法

<!DOCTYPE html>
<html>
    <head>
        <meta charset="UTF-8">
        <title>間接使用數組的方法</title>
    </head>
    <body>
        <script type="text/javascript">
            let set=new Set([1,2,3,4,5]);
            set=new Set([...set].map(x=>x*2));//使用數組的map方法
            console.log(set);//2,4,6,8,10
            let mySet=new Set([1,2,3,4,5]);
            mySet=new Set([...mySet].filter(x=>x%2==0));//使用數組的filter方法
            console.log(mySet);//2,4
        </script>
    </body>
</html>

(3):實現並集,交集,差集

<!DOCTYPE html>
<html>
    <head>
        <meta charset="UTF-8">
        <title>實現並集,交集,差集</title>
    </head>
    <body>
        <script type="text/javascript">
            let a=new Set([1,2,3]);
            let b=new Set([4,3,2]);
            //並集
            let union=new Set([...a, ...b]);
            console.log(union);//1,2,3,4
            //交集
            let intersect=new Set([...a].filter(x=>b.has(x)));
            console.log(intersect);//2,3
            //差集
            let difference=new Set([...a].filter(x=>!b.has(x)));
            console.log(difference);//1
        </script>
    </body>
</html>

(4):同步改變原來的 Set 結構

若是想在遍歷操做中,同步改變原來的 Set 結構,目前沒有直接的方法,但有兩種變通方法。一種是利用原 Set 結構映射出一個新的結構,而後賦值給原來的 Set 結構;另外一種是利用Array.from方法。json

<!DOCTYPE html>
<html>
    <head>
        <meta charset="UTF-8">
        <title>同步改變原來的 Set 結構</title>
    </head>
    <body>
        <script type="text/javascript">
            //方法一
            let set=new Set([1,2,3]);
            set=new Set([...set].map(val=>val*2));
            console.log(set);//2,4,6
            //方法二
            let mySet=new Set([1,2,3]);
            mySet=new Set(Array.from(mySet,val=>val*2));
            console.log(mySet);//2,4,6
        </script>
    </body>
</html>

5.set實例屬性和方法

(1):size屬性

<!DOCTYPE html>
<html>
    <head>
        <meta charset="UTF-8">
        <title>set中的size屬性</title>
    </head>
    <body>
        <script type="text/javascript">
            const set=new Set();
            //向set中添加成員
            set.add(1);
            set.add(2);
            set.add(3);
            //鏈式方法
            set.add(4).add(5).add(6);
            console.log(set.size);//6
        </script>
    </body>
</html>

(2):操做方法add()、delete()、has()、clear()

<!DOCTYPE html>
<html>
    <head>
        <meta charset="UTF-8">
        <title>set中的操做方法add()、delete()、has()、clear()</title>
    </head>
    <body>
        <script type="text/javascript">
            const set=new Set();
            //向set中添加成員
            set.add(1);
            set.add(2);
            set.add(3);
            //鏈式方法
            set.add(4).add(5).add(6);
            console.log(set.size);//6
            console.log(set.has(1));//true
            set.delete(1);
            console.log(set.has(1));//false
            set.clear();//清空所有set成員
            console.log(set.size);//0
        </script>
    </body>
</html>

(3):遍歷方法keys()、values()、entries()、forEach()

注意:set的遍歷順序就是插入順序,因爲set沒有鍵名,只有鍵值(或者說鍵名和鍵值是同一個值),因此keys()和values()方法的行爲徹底一致數組

<!DOCTYPE html>
<html>
    <head>
        <meta charset="UTF-8">
        <title>set中的遍歷方法keys(),values(),entries(),forEach()</title>
    </head>
    <body>
        <script type="text/javascript">
            let set=new Set(['red','blue','green']);
            //遍歷所有的key
            for(let key of set.keys()){
                console.log(key);//red,blue,green
            }
            //遍歷所有的value
            for(let value of set.values()){
                console.log(value);//red,blue,green
            }
            //遍歷所有的key和value
            for(let item of set.entries()){
                console.log(item);//['red','red'],['blue','blue'],['green','green']
            }
            set.forEach((key,value)=>{
                console.log(key+':'+value);
            })
        </script>
    </body>
</html>

Map數據結構

1.Map簡介

es6中的map很大程度上和set類似,可是map是以鍵值對的形式存儲數據的數據結構

2.經常使用的屬性和方法

  • size:返回map結構的成員總數

  • set(key,value):設置鍵名key對應的鍵值value,而後返回整個map結構,若是key已經有值,則鍵值會被更新,不然就新生成該鍵

  • get(key):讀取key對應的鍵值,若是找不到key,則返回undefined

  • has(key):返回一個布爾值,表示某個鍵是否在當前map對象中

  • delete(key):刪除某個key,返回true,若是刪除失敗,返回false

  • clear():清除全部成員,沒有返回值

  • keys():返回鍵名的遍歷器

  • values():返回鍵值的遍歷器

  • entries():返回鍵值對的遍歷器

  • forEach():遍歷map的全部成員

3.實例剖析

(1):size屬性

<!DOCTYPE html>
<html>
    <head>
        <meta charset="UTF-8">
        <title>map中的size屬性</title>
    </head>
    <body>
        <script type="text/javascript">
            const map=new Map();
            map.set('foo',true);
            map.set('bar',false);
            console.log(map.size);//2
        </script>
    </body>
</html>

(2):set(key,value)方法

<!DOCTYPE html>
<html>
    <head>
        <meta charset="UTF-8">
        <title>map中的set()方法</title>
    </head>
    <body>
        <script type="text/javascript">
            const map=new Map();
            map.set('1','a');//鍵是字符串
            map.set(2,'b');//鍵是數值
            map.set(undefined,'3');//鍵是undefined
            console.log(map);//'1'=>a,2=>b,undefinde=3
            const myMap=new Map();
            //鏈式寫法
            myMap.set(1,'a').set(2,'b').set(3,'c');
            console.log(myMap);//1=>a,2=>b,3=>c
        </script>
    </body>
</html>

(3):get(key)方法

<!DOCTYPE html>
<html>
    <head>
        <meta charset="UTF-8">
        <title>map中的get()方法</title>
    </head>
    <body>
        <script type="text/javascript">
            const map=new Map();
            const hello=function(){
                console.log('你好');
            }
            map.set(hello,'es6');//鍵是函數
            console.log(map.get(hello));//es6
        </script>
    </body>
</html>

(4):has(key)方法

<!DOCTYPE html>
<html>
    <head>
        <meta charset="UTF-8">
        <title>map中的has()方法</title>
    </head>
    <body>
        <script type="text/javascript">
            const map=new Map();
            //鏈式寫法
            map.set('a',1).set('b',2).set('c',3);//向map中添加成員
            console.log(map.has('a'));//true
            console.log(map.has('b'));//true
            console.log(map.has('c'));//true
            console.log(map.has('d'));//false
        </script>
    </body>
</html>

(5):delete(key)方法

<!DOCTYPE html>
<html>
    <head>
        <meta charset="UTF-8">
        <title>map中的delete方法</title>
    </head>
    <body>
        <script type="text/javascript">
            const map=new Map();
            map.set('a',1);
            console.log(map.has('a'));//true
            map.delete('a');//刪除鍵a
            console.log(map.has('a'));//false
        </script>
    </body>
</html>

(6):clear()方法

<!DOCTYPE html>
<html>
    <head>
        <meta charset="UTF-8">
        <title>map中的clear()方法</title>
    </head>
    <body>
        <script type="text/javascript">
            const map=new Map();
            map.set('foo',true);//向map中添加成員
            map.set('bar',false);
            console.log(map.size);//2
            map.clear();//清除map中的所有成員
            console.log(map.size);//0
        </script>
    </body>
</html>

(7):遍歷方法keys()、values()、entries()、forEach()

<!DOCTYPE html>
<html>
    <head>
        <meta charset="UTF-8">
        <title>遍歷方法keys(),values(),entries(),forEach()</title>
    </head>
    <body>
        <script type="text/javascript">
            const map=new Map();
            //向map中添加成員
            map.set(1,'a');
            map.set(2,'b');
            map.set(3,'c');
            //遍歷所有的鍵
            for(let key of map.keys()){
                console.log(key);//1,2,3
            }
            //遍歷所有的值
            for(let values of map.values()){
                console.log(values);//a,b,c
            }
            //遍歷所有的鍵和值
            for(let [key,value] of map.entries()){
                console.log(key,value);//1=>a,2=>b,3=>c
            }
            for(let item of map.entries()){
                console.log(item[0],item[1]);//1=>a,2=>b,3=>c
            }
            for(let [key,value] of map){
                console.log(key,value);//1=>a,2=>b,3=>c
            }
            map.forEach(function(value,key){
                console.log(key,value);
            })
        </script>
    </body>
</html>

注意:這裏的forEach()是值在前,鍵在後dom

(8):map結構轉爲數組

<!DOCTYPE html>
<html>
    <head>
        <meta charset="UTF-8">
        <title>map結構轉爲數組</title>
    </head>
    <body>
        <script type="text/javascript">
            const map=new Map([
                [1,'one'],
                [2,'two'],
                [3,'three']
            ]);
            console.log([...map.keys()]);//[1,2,3]
            console.log([...map.values()]);//one,two,three
            console.log([...map]);//[1,one],[2,two],[3,three]
            console.log([...map.entries()]);//[1,one],[2,two],[3,three]
            const map1=new Map(
                [...map].filter(([key,value])=>key<3)//使用數組的filter方法
            );
            console.log(map1);//1=>one,2=>two
        </script>
    </body>
</html>

4.Map與其它數據結構的轉換

做爲鍵值對存儲數據的map與其它數據也能夠進行轉換,咱們看下下面的案例函數

(1)Map轉爲數組

 map轉爲數組最方便的方法,就是使用擴展運算符...

<!DOCTYPE html>
<html>
    <head>
        <meta charset="UTF-8">
        <title>Map轉爲數組</title>
    </head>
    <body>
        <script type="text/javascript">
            const map=new Map();//建立map數據結構
            map.set(true,7);//向map中添加成員
            map.set({foo:3},['abc']);
            console.log([...map]);//[[true,7],[{foo:3},['abc']]];
        </script>
    </body>
</html>

(2)數組轉爲Map

 將數組傳入map構造函數,就能夠轉爲map

<!DOCTYPE html>
<html>
    <head>
        <meta charset="UTF-8">
        <title>數組轉爲map</title>
    </head>
    <body>
        <script type="text/javascript">
            const map=new Map([
                [true,7],
                [{foo:3},['abc']]
            ]);
            console.log(map);
            //map{
                //true=>7,
                //object:{foo:3}=>['abc'];
            //}
        </script>
    </body>
</html>

(3)Map轉爲對象

若是全部map的鍵都是字符串,它能夠無損的轉爲對象,若是有非字符串的鍵名,那麼這個鍵名會被轉爲字符串,再做爲對象的鍵名

<!DOCTYPE html>
<html>
    <head>
        <meta charset="UTF-8">
        <title>map轉爲對象</title>
    </head>
    <body>
        <script type="text/javascript">
            function strMapObj(strMap){
                let obj=Object.create(null);//建立一個新對象
                for(let [key,value] of strMap){//遍歷循環strMap
                    obj[key]=value;
                }
                return obj;
            }
            const map=new Map().set('yes',true).set('no',false);
            console.log(strMapObj(map));//{yes:true,no:false}
        </script>
    </body>
</html>

在這裏了我須要講解一下Object.create()這個方法,官方的意思是:Object.create()方法建立一個新對象,使用現有的對象來提供新建立的對象的__proto__

<!DOCTYPE html>
<html>
    <head>
        <meta charset="UTF-8">
        <title>測試Object.create()方法</title>
    </head>
    <body>
        <script type="text/javascript">
            const person={
                isHuman: false,
                  printIntroduction: function () {
                    console.log(this.name,this.isHuman);
                  }
            }
            const me = Object.create(person);
            me.name = "Matthew";
            me.isHuman = true;
            me.printIntroduction();//Mattew,true
        </script>
    </body>
</html>

(4)對象轉爲Map

<!DOCTYPE html>
<html>
    <head>
        <meta charset="UTF-8">
        <title>對象轉爲map</title>
    </head>
    <body>
        <script type="text/javascript">
            function objToMap(obj){
                let map=new Map();
                for(let key of Object.keys(obj)){
                    map.set(key,obj[key]);
                }
                return map;
            }
            console.log(objToMap({yes:true,no:false}));//yes=>true,no=>false
        </script>
    </body>
</html>

在這裏講解Object.keys()方法,官方解釋:Object.keys() 方法會返回一個由一個給定對象的自身可枚舉屬性組成的數組,數組中屬性名的排列順序和使用,for..in循環遍歷該對象時返回的順序一致 。若是對象的鍵-值都不可枚舉,那麼將返回由鍵組成的數組

參數:要返回其枚舉自身屬性的對象

返回值:一個表示給定對象的全部可枚舉屬性的字符串數組

// simple array
var arr = ['a', 'b', 'c'];
console.log(Object.keys(arr)); // console: ['0', '1', '2']

// array like object
var obj = { 0: 'a', 1: 'b', 2: 'c' };
console.log(Object.keys(obj)); // console: ['0', '1', '2']

// array like object with random key ordering
var anObj = { 100: 'a', 2: 'b', 7: 'c' };
console.log(Object.keys(anObj)); // console: ['2', '7', '100']

// getFoo is a property which isn't enumerable
var myObj = Object.create({}, {
  getFoo: {
    value: function () { return this.foo; }
  } 
});
myObj.foo = 1;
console.log(Object.keys(myObj)); // console: ['foo']

(5)Map轉爲JSON字符串

map轉爲json要區分兩種狀況,一種狀況時map的鍵名都是字符串,這時能夠選擇轉爲對象json,另外一種狀況是map的鍵名有非字符串,這時能夠選擇轉爲數組json。

<!DOCTYPE html>
<html>
    <head>
        <meta charset="UTF-8">
        <title>map轉爲json</title>
    </head>
    <body>
        <script type="text/javascript">
            function strMapToObj(strMap){
                let obj=Object.create(null);//建立一個新對象
                for(let [key,value] of strMap){
                    obj[key]=value;
                }
                return obj;
            }
            function strMapToJson(strMap){
                return JSON.stringify(strMapToObj(strMap));
            }
            let map=new Map().set('yes',true).set('no',false);
            let obj=strMapToJson(map);
            console.log(obj);//{'yes':true,'no':false}
            function mapToArrayJson(map){
                return JSON.stringify([...map]);
            }
            let fooMap=new Map().set(true,7).set({foo:3},['abc']);
            let foo=mapToArrayJson(fooMap);
            console.log(foo);//[[true:7],[{foo:3},['abc']]]
        </script>
    </body>
</html>

(6)JSON字符串轉爲Map

json轉爲map,正常狀況下全部鍵名都是字符串,可是有一種特殊狀況,整個json就是一個數組,且每一個數組成員自己,又是一個有兩個成員的數組,這時它能夠一一對應的轉爲map,這每每是map轉爲數組json的逆操做。

<!DOCTYPE html>
<html>
    <head>
        <meta charset="UTF-8">
        <title>json轉爲map</title>
    </head>
    <body>
        <script type="text/javascript">
            function objTostrMap(obj){
                let map=new Map();
                for(let key of Object.keys(obj)){
                    map.set(key,obj[key]);
                }
                return map;
            }
            function jsonToStrMap(jsonStr){
                return objTostrMap(JSON.parse(jsonStr));
            }
            let obj1=jsonToStrMap('{"yes": true, "no": false}')
            console.log(obj1);//yes=>true,no=>false
            function jsonToMap(jsonStr){
                return new Map(JSON.parse(jsonStr));
            }
            let obj2=jsonToMap('[[true,7],[{"foo":3},["abc"]]]')//true=>7,{foo:3}=>['abc']
            console.log(obj2);
        </script>
    </body>
</html>

參考資料:http://es6.ruanyifeng.com/#docs/set-map

總結

本章咱們主要學習了ES6中set和map相關的屬性和方法,set和map的方法中有不少都是相同的方法,has()、delete()、clear()、keys()、values()、entries、forEach()等等。

相關文章
相關標籤/搜索