javascript : 2つの配列を比較して、差分(増分,減分)を取得


proxy で配列の変更を検知したあとの処理で、「変更前の配列」と「変更後の配列」を比較したくなりました。

以下、2つの配列を受け取って、増分値と減分値の配列をオブジェクトで返す関数です。

※ ttatsf 様から、より良いコードをコメント欄にて頂いております。断然、そちらの方が参考になると思います


// 配列の差異を取得する処理
const get_difference = ( _old_arr, _next_arr ) => {

  const additions = _next_arr.filter(
    _next => ! _old_arr.includes( _next )
  );

  const subtractions = _old_arr.filter(
    _old => ! _next_arr.includes( _old )
  );

  return {
    additions : additions,       //  増えた分
    subtractions : subtractions  //  減った分
  };
}

以下、関数の挙動を確かめます。


//  要素を増やします
const arr1 = [ 1, 2, 3 ];
const arr2 = [ ...arr1, 4, 5 ];

const result1 = get_difference( arr1, arr2 );
console.log( result1.additions );      //  [ 4, 5 ]
console.log( result1.subtractions );   //  []

//  要素を増減させます
const arr3 = [ 'a', 'b', 'c', 'd' ];
const arr4 = [ 'a', 'b', 'e', 'f' ];

const result2 = get_difference( arr3, arr4 );
console.log( result2.additions );      // [ 'e', 'f' ]
console.log( result2.subtractions );   // [ 'c', 'd' ]

もっといい方法があったら、ぜひ教えてください。

以下、おまけです。(proxy で用いた例です)


let obj = {
  array : [ 1, 2, 3 ]
}

let proxy = new Proxy( obj, {
  set( _obj, _prop, _next ){

    const old = _obj[ _prop ];

    if( _prop === 'array' ){
      const difference = get_difference( old, _next );
      console.log( 'additions : ' + difference.additions );
      console.log( 'subtractions : ' + difference.subtractions );
    }
    _obj[ _prop ] = _next;
    return true;
  }
} );

proxy.array = [ ...obj.array, 4, 5 ];
//  additions : 4, 5

proxy.array = [ 1, 2, 4, 6 ];
//  additions : 6
//  subtrctions 3, 5

(2020.1.16 追記)
 ttatsf 様よりコメントを頂きました。ありがとうございます。
 ご指摘いただきました通り、set について、返り値の記述が抜けておりました。 大変申し訳ございません。
 「return true」を加えたものに修正させていただきました。
 また、includes() を使用したものに差し替えさせていただきました。