Tech Blog - mixross

Immutable.jsでレコードセット(MapのList)を操作

このエントリーをはてなブックマークに追加
LINE

概要

JSでオブジェクトの配列(DBのレコードセットのイメージ)をimmutableに扱ったときのメモ。

下のようなサンプルデータがあり、キーがidとなっている。

const base = [
  {id: 1, name: 'item-a', price: 100},
  {id: 2, name: 'item-b', price: 200},
  {id: 3, name: 'item-c', price: 300},
  {id: 4, name: 'item-d', price: 400},
]

これに対して、以下の4つのパターンのスニペットを挙げる。

  • 単一レコードを更新 (追加は行わない)
  • 複数レコードを更新 (追加は行わない)
  • 単一レコードを追加or更新
  • 複数レコードを追加or更新

単一レコードを更新

const update = {id: 2, name: 'item-f', price: 800}

const result = Immutable
  .fromJS(base)
  .map((v) => {
      return v.get('id') == update.id ? v.merge(update) : v
    }
  )
  .toJS()

複数レコードを更新

const update = [
  {id: 2, name: 'item-f', price: 800},
  {id: 4, name: 'item-e', price: 600},
]

const result = Immutable
  .fromJS(base)
  .map((a) => {
      const c = Immutable.fromJS(update).find((b) => a.get('id') == b.get('id'))
      return !!c ? a.merge(c) : a
    }
  )
  .toJS()

単一レコードを追加or更新

const update = {id: 2, name: 'item-f', price: 800}  // 更新
// const update = {id: 5, name: 'item-f', price: 800}    // 追加

const match = base.find(v => v.id == update.id)

const result =
  !!match
  ?
  Immutable
    .fromJS(base)
    .map((v) => {
        return v.get('id') == update.id ? v.merge(update) : v
      }
    )
    .toJS()
  :
  Immutable
    .fromJS(base)
    .push(update)
    .toJS()

複数レコードを追加or更新

const update = [
  {id: 2, name: 'item-f', price: 800},  // 更新
  {id: 5, name: 'item-e', price: 600},  // 追加
]

let result = Immutable.fromJS(base).toJS()

update.forEach(u => {
  const match = result.find(v => v.id == u.id)
  
  result =
    !!match
    ?
    Immutable
      .fromJS(result)
      .map((v) => {
          return v.get('id') == u.id ? v.merge(u) : v
        }
      )
      .toJS()
    :
    Immutable
      .fromJS(result)
      .push(u)
      .toJS()
})
RSS