LoginSignup
2
2

More than 5 years have passed since last update.

Immutable.js: オブジェクトのListからMapへの変換

Last updated at Posted at 2018-03-20

ドキュメントをちゃんと読むと書いてあったけど、頻出な気がするのでここに書き残しておく。ちなみに、ここでやるMapへの変換はOrderedMapへも同様に変換できる。

Mapの利点

Listにオブジェクトを格納するようなケースだと、比較的Mapが適していることが多い。例えば、以下のように固有の識別子を持つオブジェクトが存在するとする。

class Book {
  constructor(id, name) {
    this.id = id;
    this.name = name;
  }
}

アプリケーションの中でListからidを指定して任意のBookを取得したいときには以下のようにfindなどを使うかと思う。

List
const findBookById = id => 
  bookList.find(book => book.id === id);

ここでMapを使うと、より簡潔に検索処理を実装できるうえ、配列走査が必要なくなるためパフォーマンスの点でも利点がある

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を使うことにした。

2
2
0

Register as a new user and use Qiita more conveniently

  1. You get articles that match your needs
  2. You can efficiently read back useful information
  3. You can use dark theme
What you can do with signing up
2
2