はじめに
連想配列は、ObjectではなくMapを使ったほうが良い(こともある)という記事を読み、積極的に使うことにしました。
参考:
Mapを使うにあたり、「こうしたいときどうするんだっけ?」となった時に参考にできるものが欲しかったので、自分で記事にまとめることにしました。
この記事について
以下について書いています
- Mapのメンバ
- Mapでよく使う操作
以下については書いていません
- そもそも配列とは何か
- Object配列との違い
連想配列とは何か
連想配列とは・・・
添え字にスカラー数値以外のデータ型(文字列型等)も使用できる配列である。
連想配列は、配列の値(value
)に名前(key
)をつけて管理することができます。
// Arrayだと名前はつけられないconstarrayTestResults=newArray(77,91,82)// Mapだと名前をつけられるconstmapTestResults=newMap([['国語',77],['数学',91],['英語',82],]);
参考:
配列の宣言
宣言だけする
constmap=newMap()
宣言と同時に初期値を設定する
consttestResults=newMap([['国語',77],['数学',91],['英語',82],]);
メンバ
一覧
名称 | 説明 |
---|---|
.size | 要素数を取得する |
.has(key) | keyが一致する要素の有無を真偽値で取得する |
.get(key) | keyが一致する要素の値を取得する |
.set(key,value) | keyが一致する要素の値を上書き(または追加)する |
.delete(key) | keyが一致する要素を削除する |
.clear() | 全ての要素を削除する |
.keys() | 全ての要素のkeyを取得する |
.values() | 全ての要素のvalueを取得する |
.entries() | 全ての要素のkeyとvalueを取得する |
.forEach(callback[, thisArg]) | 引数のcallbackに渡した処理をそれぞれの要素に実行する |
.size
要素数を取得します。
consttestResults=newMap([['国語',77],['数学',91],['英語',82],['理科',55],['地理',60],['歴史',49],]);constsize=testResults.size// 6
*プロパティなのでカッコ()
が不要です。size()
ではなくsize
と書きます。
.has(key)
keyが一致する要素の有無を真偽値で取得します
consttestResults=newMap([['国語',77],['数学',91],['英語',82],]);consthasEnglishResult=testResults.has('英語');// trueconsthasHistoryResult=testResults.has('理科');// false
.get(key)
keyが一致する要素の値を取得します。
keyが一致する要素がなかった場合はundifined
を取得します。
consttestResults=newMap([['国語',77],['数学',91],['英語',82],]);constenglishResult=testResults.get('英語');// 82consthistoryResult=testResults.get('理科');// undefined
.set(key,value)
keyが一致する要素の値を上書きします。
keyが一致する要素が存在しない場合、新たに要素を追加します。
consttestResults=newMap([['国語',77],['数学',91],['英語',82],]);// 上書きtestResults.set('英語',100);// Map {// '国語' => 77,// '数学' => 91,// '英語' => 100,// }// 追加testResults.set('理科',55);// Map {// '国語' => 77,// '数学' => 91,// '英語' => 100,// '理科' => 55,// }
.delete(key)
keyが一致する要素を削除します。
削除ができたかどうかを有無を真偽値で取得することもできます。
consttestResults=newMap([['国語',77],['数学',91],['英語',82],]);console.log(testResults.delete('数学'));// true// Map {// '国語' => 77,// '英語' => 82,// }console.log(testResults.delete('理科'));// false// Map {// '国語' => 77,// '英語' => 82,// }
.clear()
全ての要素を削除します。
consttestResults=newMap([['国語',77],['数学',91],['英語',82],['理科',55],['地理',60],['歴史',49],]);console.log(testResults.clear());// Map {}
.keys()
全ての要素のkeyを取得します。
consttestResults=newMap([['国語',77],['数学',91],['英語',82],]);constkeys=testResults.keys();// [Map Iterator] {// '国語',// '数学',// '英語'// }
*実行結果はシンボルという特殊な型で出力されます。
配列として扱う方法は次章「よく使う操作」で説明します。
.values()
全ての要素のvalueを取得します。
consttestResults=newMap([['国語',77],['数学',91],['英語',82],]);constvalues=testResults.values();// [Map Iterator] {// 77,// 91,// 82// }
*実行結果はシンボルという特殊な型で出力されます。
配列として扱う方法は次章「よく使う操作」で説明します。。
.entries()
全ての要素のkeyとvalueを取得します。
consttestResults=newMap([['国語',77],['数学',91],['英語',82],]);constentries=testResults.entries();// [Map Entries] {// ['国語', 77],// ['数学', 91],// ['英語', 82]// }
*実行結果はシンボルという特殊な型で出力されます。
配列として扱う方法は次章「よく使う操作」で説明します。
.forEach(callback[, thisArg])
引数のcallback
に渡した処理を要素それぞれの要素に実行します。
Array.prototype.forEach()と同じような動きをします。
// forEach()consttestResults=newMap([['国語',77],['数学',91],['英語',82],]);testResults.forEach((value,key,map)=>{console.log(value,key,map);});// 77 国語 Map { '国語' => 77, '数学' => 91, '英語' => 82 }// 91 数学 Map { '国語' => 77, '数学' => 91, '英語' => 82 }// 82 英語 Map { '国語' => 77, '数学' => 91, '英語' => 82 }
よく使う操作
Iteratorを配列として扱う
keys()やvalues()の実行結果はシンボルという特殊な型で出力されます。
配列ではないので、配列用の関数を実行するとエラーになります。
consttestResults=newMap([['国語',77],['数学',91],['英語',82],]);constkeys=testResults.keys();// [Map Iterator] {// '国語',// '数学',// '英語',// }keys.forEach((key)=>console.log(key));// TypeError: keys.forEach is not a function
参考:
方法1. Array.from()
配列として値を取得したい場合は、Array.from()
を使って変換すればOKです。
consttestResults=newMap([['国語',77],['数学',91],['英語',82],]);constkeys=Array.from(testResults.keys());// [// '国語',// '数学',// '英語'// ];keys.forEach((key)=>console.log(key));// 国語// 数学// 英語
方法2. 分割代入([...配列]
)
分割代入[...Map.keys()]
を利用して配列にすることも可能です。
consttestResults=newMap([['国語',77],['数学',91],['英語',82],]);constkeys=[...testResults.keys()];// [// '国語',// '数学',// '英語'// ];keys.forEach((key)=>console.log(key));// 国語;// 数学;// 英語;
キーでソートする
数値のkeyを数の若い順に並び替えます
consttestResults=newMap([[6,'歴史'],[1,'国語'],[4,'理科'],[5,'地理'],[2,'数学'],[3,'英語'],]);constsortedTestResults=newMap([...testResults.entries()].sort((a,b)=>a[0]-b[0]));// Map {// 1 => '国語',// 2 => '数学',// 3 => '英語',// 4 => '理科',// 5 => '地理',// 6 => '歴史'// }
参考:
Stack Overflow -Is it possible to sort a ES6 map object?-
最大値を取得する
値の中で最大の数値を取得します。
consttestResults=newMap([['国語',77],['数学',91],['英語',82],['理科',55],['地理',60],['歴史',49],]);constmaxNum=Math.max(...Array.from(testResults.values()));// 91
重複する値の数をカウントする
配列内の同じ値の出現回数を要素ごとにカウントします。
constanimals=['いぬ','ねこ','いぬ','ねこ','いぬ','いぬ'];constanimalCounts=newMap();for(letanimalofanimals){// 一致するkeyがあればカウントアップif(animalCounts.has(animal)){constcount=animalCounts.get(animal);animalCounts.set(animal,count+1);// 一致するkeyがなければ新たに値をset}else{animalCounts.set(animal,1);}}console.log(animalCounts);// Map {// 'いぬ' => 4,// 'ねこ' => 2,// }
まとめ
メンバは直感的にわかるものばかりなので覚えやすいのですが、配列への変換操作にはまだ慣れません。。
ネットで調べようとしても、Array.prototype.map()とかObjectの連想配列が混ざっててなかなか目的のものが手に入らないんですよね。
ググラビリティの問題かもですが、、
覚えるまでは、この記事をみながら使おうと思います。