【JavaScript】複数のオブジェクトへのマップ的配列を複数用意して高速化

 JavaScript の値の挙動は少々独特です。例は次のコードとデモです。

const base = [
  {first: 1, second: 1, msg:''},
  {first: 2, second: 3, msg:''},
  {first: 5, second: 8, msg:''},
];
const firstIsEvenList = base.filter(i => i.first % 2 === 0);// baseのうちの一部だけ格納
const secondIsOddList = base.filter(i => i.second % 2 === 1);// baseのうちの一部だけ格納

// msg を書き換え
const msgWriteByFIEL = () => {
  firstIsEvenList.forEach(i=>i.msg='first は偶数')
}
// msg を書き換え
const msgWriteBySIOL = () => {
  secondIsOddList.forEach(i=>i.msg='second は奇数')
}
// msg を表示
const msgDisplay = () => document.querySelector('.console').innerText = JSON.stringify(base, null, 2)

// msg を順々に書き換え
function start(){
  base.forEach(i => i.msg = `${i.first},${i.second}`);
  msgDisplay();  
  setTimeout(()=>{
    msgWriteByFIEL();
    msgDisplay();    
    setTimeout(()=>{
      msgWriteBySIOL();
      msgDisplay();  
    },2000)
  },2000)
}

 要するに値の大本が変わっても、ネストの先にあるオブジェクトのプロパティ等の値は共通であるという挙動です。これを利用することで巨大なオブジェクト、配列の操作を高速化できます。
 例にある以下の大本の加工後の値を格納する変数を用意し、この変数を起点に子のオブジェクトを操作することで配列の一部を抜き出す処理をメモ化できます。

const firstIsEvenList = base.filter(i => i.first % 2 === 0);// baseのうちの一部だけ格納
const secondIsOddList = base.filter(i => i.second % 2 === 1);// baseのうちの一部だけ格納

 配列の一部に対してなんやかんやしなければならないが配列の一部を切り出す回数を節約する時なんかに便利です。毎回 filter メソッドを使うと全件検索のループ数が増えるので処理の発生するタイミングや処理内容によっては案外影響が出ます。コード量もまあまあ増えます。
 利点ばかりを紹介しましたが、この挙動を利用したコードはまあまあハックな方です。代わりになる機能がある環境ならば(Vue.js の computed、React の memo など)そちらを使い、そうでなくても 1 関数内などの閉じた範囲で取り扱った方が無難です。この方法は値がどこから参照され、どこで変化しているか非常にわかりにくくなります。

>株式会社シーポイントラボ

株式会社シーポイントラボ

TEL:053-543-9889
営業時間:9:00~18:00(月〜金)
住所:〒432-8003
   静岡県浜松市中央区和地山3-1-7
   浜松イノベーションキューブ 315
※ご来社の際はインターホンで「316」をお呼びください

CTR IMG