LoginSignup
5
2

More than 3 years have passed since last update.

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

Last updated at Posted at 2020-01-15

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() を使用したものに差し替えさせていただきました。

5
2
1

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
5
2