ES6(MapとSet)

はじめに

データを管理するための入れ物としての役割を持つMap,Setについて、Map,Setの使い方やObjectやArrayとの違いを紹介していきます。

Map,Setの使い方

1.new演算子でMap,Set(入れ物)を生成

//Map
const map = new Map();
//Set
const s = new Set();

2.データを追加する

//Map
const map = new Map();
const key1 = "prop1";
map.set(key1, 0); //keyとvalueを紐付け
console.log(map); //Map(1) {"prop1" => 0}
//省略形
const map1 = new Map([["prop1", 0]]);
console.log(map1);//Map(1) {"prop1" => 0}

//Set
const s = new Set();
const key1 = "prop1";
s.add(key1);
console.log(s); //Set(1) {"prop1"}

3.データの削除(MapもSetも同様)

const map = new Map;
const key1 = 'prop1';
map.set(key1, 0);
map.delete(key1)
console.log(map);//Map(0) {}

Object vs. Map

①キーの制約

(Mapのキーの制約はない)

const map = new Map();
const key1 = {};//object でもOK
map.set(key1, 0);
const key2 = function () {};//関数でもOK
map.set(key2, 1);
console.log(map);//Map(2) {{…} => 0, ƒ => 1}

オブジェクトのキーは文字列という制約があります。文字列以外でキーを設定するとエラーが起きます。

const obj = {
  {}: 1,
};//Uncaught SyntaxError: Unexpected token '{'

因みにオブジェクトのキーをnumber型やboolean型で設定したとしても文字列で自動変換されます。

const obj = {
  0: 1,
  true: 2,
};
console.log(Object.keys(obj));//(2) ["0", "true"]
②Mapではfor...ofが使える
const map = new Map();
const key1 = {};//object でもOK
map.set(key1, 0);
const key2 = function () {};//関数でもOK
map.set(key2, 1);
for (const [k,v] of map) { //[]で分割代入の利用
  console.log(k,v);//{} 0,ƒ () {} 1
}
③Mapではfor...inが使えない
const map = new Map();
const key1 = {};//object でもOK
map.set(key1, 0);
const key2 = function () {};//関数でもOK
map.set(key2, 1);
for (const [k, v ] in map) {
  console.log(k,v); 
}

エラーを表示してほしいですが、コンソール上には何も表示されません。
オブジェクトではfor...inが使えます。ES6(for...of)の記事

Array vs. Set

①重複値を持つ、持たない

ご存知、arrayは値が重複値を持ちます。

const arry = ['value1', 'value1']
console.log(arry);//(2) ["value1", "value1"]

その逆でSetは重複値を持ちません。

const s =new Set(['value1','value1'])
console.log(s);//Set(1) {"value1"}

使い道があるとは思いませんが、SetからArrayに変更することは可能です。

const s = new Set(["value1", "value1"]);
const arry = [...s]; //スプレッド構文の利用
console.log(arry);  //['value1']

//または
const s = new Set(["value1", "value1"]);
const arry = Array.from(s);
console.log(arry); ////['value1']

ここで面白いのは配列に変換された中身が重複値を持たない形で出力されています。これはSetの性能を引き継いでるからでしょうか?そういう仕様でしょうか? 
どうでもいいわ!と思われた方もいらっしゃると思いますが、少し気になったのでこすりました。ただ配列に変更すれば、通常の配列のように重複値を持つようになります。

const s = new Set(["value1", "value1"]);
const arry = [...s];
arry[1] = "value1";
console.log(arry); //(2) ["value1", "value1"]
②for...in,for...ofについて

反復処理についてはArrayに軍配が上がります。arrayはfor...in,for...ofどちらも使えるのに対して、Setはfor...ofは使えますが、for...inは使えません。

const s = new Set(["value1", "value2"]);
for (const key in s) {
  console.log(key); //何も出力されません。
  }

以上より、for...in,for...ofなどの反復処理にはSetよりArrayを使いましょう。