🐥

【JS】Map/Setについて

2021/10/07に公開

JavaScriptでデータの集まりを扱うコレクションは、配列だけではありません。

他にもMapとSetと言ったものがあります。

今回は、その2つについて解説していきます。

Map


Mapとは

Mapはキーと値の組み合わせからなるコレクションのことです。

いわゆる、辞書や連想配列というものになります。

要は、オブジェクトと同じ感じのものです。

ただ、オブジェクトにはいくつかの問題あったので、それを解消しようとして作られたのがこのMapになります。

具体的に、オブジェクトとMapの違いとしては、

  • キーとして文字列以外を扱える
  • Objectのprototypeオブジェクトから継承されたプロパティを持たない
  • マップのサイズを簡単に知ることができる

と言った点が挙げられます。

ただ、オブジェクトの方が扱いが簡単だったり、JSONへの変換が容易なので便利です。

なので、Mapは必要な時だけ使えばOKです。

基本的な使い方

  • 作成と初期化

newすることで、Mapを作成することができます。

また、sizeメソッドで要素数を知ることができます。


const map = new Map([
  ["key1", "value1"],
  ["key2", "value2"]
]);

// 2
console.log(map.size);

  • 要素の追加と取り出し

要素の追加にはsetメソッド、取り出しにはgetメソッドが使えます。

また、対象のキーがあるかどうか判断するにはhasメソッドが使えます。


const map = new Map([
  ["key1", "value1"],
  ["key2", "value2"]
]);

map.set("key", "value3");
// value3
console.log(map.get("key"));
// true
console.log(map.has("key"));

  • 要素の削除

要素を1つ消したい時はdeleteメソッド、全て消したい時はclearメソッドが使えます。


const map = new Map([
  ["key1", "value1"],
  ["key2", "value2"]
]);

// 2
console.log(map.size);
map.delete("key1");
// 1
console.log(map.size);
map.clear();
// 0
console.log(map.size);

反復処理

マップが持つ要素を列挙するメソッドとして、forEach、keys、values、entriesがあります。

forEachメソッドはマップが持つすべての要素を、マップへの挿入順に反復処理します。

コールバック関数には引数として値、キー、マップの3つが渡されます。


const map = new Map([
  ["key1", "value1"],
  ["key2", "value2"]
]);

const results = [];
map.forEach((value, key, map) => {
  results.push(`${key}:${value}`);
  // ["key1:value1", "key2:value2"]
  console.log(map);
});

// => ["key1:value1","key2:value2"]
console.log(results);

keysメソッドは、マップが持つすべての要素のキーを挿入順に並べたIteratorオブジェクトを返します。

同様に、valuesメソッドはマップが持つすべての要素の値を挿入順に並べたIteratorオブジェクトを返します。

そして、entriesメソッドはマップが持つすべての要素をエントリーとして挿入順に並べたIteratorオブジェクトを返します。

次の例のようにfor...of文で反復処理を行ったりするのが一般的です。


const map = new Map([
  ["key1", "value1"],
  ["key2", "value2"]
]);

const keys = [];
for (const key of map.keys()) {
  keys.push(key);
}
// ["key1","key2"]
console.log(keys);

const values = [];
for (const key of map.values()) {
  values.push(key);
}
// ["value1", "value2"]
console.log(values);

const entries = [];
for (const [key, value] of map.entries()) {
  entries.push(`${key}:${value}`);
}
// ["key1:value1","key2:value2"]
console.log(entries);

ちなみに、マップ自身もIterableなオブジェクトなので、for...of文で反復処理できます。

Set


Setとは、重複する値がないコレクションです。

配列と違って要素は順序を持たず、インデックスによるアクセスはできないのでそこは注意が必要です。

作成と初期化

Mapと同じようにnewすることで新しいセットを作成できます。


// "value"が重複するため、片方は無視される
const set = new Set(["value", "value", "value2"]);
// セットのサイズは2になる
console.log(set.size); // => 2

追加と削除

Setに値を追加したい場合は、addメソッドが使えます。

また、存在を確認したい場合は、hasメソッドで確認ができます。

そして、setと同じように値の削除にはdeleteとclearメソッドが使えます。


const set = new Set();

// 値の追加
set.add("a");
set.add("b");
console.log(set.size); // => 2

// 重複する値は追加されない
set.add("a");
console.log(set.size); // => 2

// 値の存在確認
console.log(set.has("a")); // => true
console.log(set.has("b")); // => false

set.delete("a");
console.log(set.size); // => 1

set.clear();
console.log(set.size); // => 0

反復処理

Setの反復処理には、forEachメソッドが使えます。

また、mapと同じようにvalues, keys, entriesが使えますがちょっと変わった動きをするので使うことはほぼないと思います。

反復処理は普通にsetに対してfor...ofをするのが一般的かと思います。

const set = new Set(["a", "b"]);
const results = [];

for (const value of set) {
    results.push(value);
}
// ["a","b"]
console.log(results);

おわりに


今回は、mapとsetについて解説してきました。

正直、使う機会はそこまで多くないと思うので、こんなのもあるんだな程度に覚えておけばOKです。

また、僕のブログではReactエンジニアになるためのロードマップを無料で全て公開しているので、参考にどうぞ。バックエンドエンジニアを目指している方などにも役立つ情報を書いてます。

https://hinoshin-blog.com/react-roadmap/

おわり

Discussion