ドキュメントをちゃんと読むと書いてあったけど、頻出な気がするのでここに書き残しておく。ちなみに、ここでやるMapへの変換はOrderedMapへも同様に変換できる。
Mapの利点
Listにオブジェクトを格納するようなケースだと、比較的Mapが適していることが多い。例えば、以下のように固有の識別子を持つオブジェクトが存在するとする。
class Book {
constructor(id, name) {
this.id = id;
this.name = name;
}
}
アプリケーションの中でListからid
を指定して任意のBookを取得したいときには以下のようにfindなどを使うかと思う。
const findBookById = id =>
bookList.find(book => book.id === id);
ここでMapを使うと、より簡潔に検索処理を実装できるうえ、配列走査が必要なくなるためパフォーマンスの点でも利点がある
const findBookById = id => bookList.get(id);
つまり、アプリケーションで常にユニークな識別子をもつオブジェクト群の格納と検索を行う場合にはListよりもMapのほうが適している
Mapの生成
一般的なのはこのようにObjectからMapへの変換
const newMap = Map({
key1: 'value1',
key2: 'value2'
})
上に加えて、ArrayからMapへの変換も用意されている! これを活用するとListからMapへの変換ができる
const newMap = Map([
['key1', 'value1'],
['key2', 'value2']
])
ListからMap
たとえば以下のようにid
などの要素を持っているオブジェクトのListがあるとする。前提として重複しているので、これをid
でユニークなMapにしたい。
class Book {
constructor(id, refId) {
this.id = id;
this.refId = refId;
}
}
// ...
const bookList = Immutable.List([
new Book(1, 2),
new Book(1, 2),
new Book(1, 2),
new Book(2, 3),
new Book(2, 3),
new Book(3, 4),
new Book(10, 4),
])
このbookList
を、id
をユニークなキーにしたMapに変換したいときにはこのようにする。
const bookListUnique = Immutable.Map(
bookList.map(book => [book.id, book])
);
オブジェクトを要素に持つListだと、単純にbookList.toMap()
では気を利かしてくれないので、このような変換が必要になる。
MapじゃなくてSetじゃない?
Immutable.jsはSetをA Collection of unique values
として定義しているが、実際には以下のようなコードがうごいてしまう。
const bookSet = I.Set([
new Book(1, 2),
new Book(1, 2),
new Book(1, 2),
new Book(2, 3),
new Book(2, 3),
]);
文字列や数値であればもちろん重複を排除してくれるが、オブジェクトではそうならないため、注意が必要になる。なので、今回自分はMapを使うことにした。