import isObject from './is-object';
/**
* @module arrayDiff
* @description Returns an object containing the added and removed items between two arrays.
*
* @since 4.0.7
*
* @param {Array} fromArr The from array.
* @param {Array} toArr The to array.
* @param {string|Function} key The key to use for the comparison. If a function is provided, it will be used to get the key.
*
* @return {object} An object containing the added and removed items.
*
* @example
* const fromArr = [ 1, 2, 3 ];
* const toArr = [ 1, 2, 3, 4, 5 ];
* const diff = arrayDiff( fromArr, toArr );
* console.log( diff );
* // { added: [ 4, 5 ], removed: [] }
*
* @example
* const fromArr = [ { id: 1, name: 'John' }, { id: 2, name: 'Jane' } ];
* const toArr = [ { id: 1, name: 'John' }, { id: 2, name: 'Jane' }, { id: 3, name: 'Joe' } ];
* const diff = arrayDiff( fromArr, toArr, 'id' );
* console.log( diff );
* // { added: [ { id: 3, name: 'Joe' } ], removed: [] }
*
*/
const arrayDiff = ( fromArr = [], toArr = [], key = null ) => {
const getValue = ( item ) => {
if ( key !== null ) {
if ( typeof key === 'function' ) {
return key( item );
} else if ( isObject( item ) ) {
return item[ key ];
}
}
return item;
};
const fromArrValues = new Set( fromArr.map( getValue ) );
const toArrValues = new Set( toArr.map( getValue ) );
const added = toArr.filter( ( item ) => ! fromArrValues.has( getValue( item ) ) );
const removed = fromArr.filter( ( item ) => ! toArrValues.has( getValue( item ) ) );
return {
added,
removed,
};
};
export default arrayDiff;