简体   繁体   中英

Compare arrays of objects and return new array of objects that are not in one of the arrays

I have been having trouble trying to figure out how to get this to work.

Basically, I have two arrays. These arrays will contain objects.

The first array, is an array of objects containing the user's favourite stations.

The second array, is an array of objects containing the stations that need to be removed.

I'd like to compare the first and second array, and return a new array that contains the stations that were not in in the remove stations array...

For example...

const favourites = [{ station_name: 'Kyle of Lochalsh', crs_code: 'KYL' }, { station_name: 'Connel Ferry', crs_code: 'CON' }, { station_name: 'Oban', crs_code: 'OBN' }]

const toBeRemoved = [{ station_name: 'Kyle of Lochalsh', crs_code: 'KYL' }]

I would then expect an array containing the other 2 stations to be returned...

I have spent hours trying to figure out how to do it, but just doesn't seem to work!!

TIA

The following code demonstrates that two object with the same properties may not be considered equal:

const ob_1={color:'black', size:'big'},  
      ob_2={color:'black', size:'big'};  
console.log(ob_1==ob_2); // false  

So we need to make a deep comparison always:

 const favourites = [ { station_name: 'Kyle of Lochalsh', crs_code: 'KYL' }, { station_name: 'Connel Ferry', crs_code: 'CON' }, { station_name: 'Oban', crs_code: 'OBN' } ]; const toBeRemoved = [ { station_name: 'Kyle of Lochalsh', crs_code: 'KYL' } ]; console.log( // Array.filter applies our custom function to each item in the // `favourites` array and returns a new (smaller) array containing // all items for which our custom function returns true favourites.filter( // Our custom function (using "arrow function" syntax) takes // a station object and uses `Array.some` to compare it to each // item in the `toBeRemoved` array. Our custom function returns // true if the current station is not in `toBeRemoved`. (station) => // Array.some takes another custom function which is applied // to each item in `toBeRemoved`, returning true if this // custom function returns true for at least one item.toBeRemoved,some( // This custom function takes a station object (called `st`) // and "deeply" compares each property against the same // property in the current station of the `favorites` // array. returning true if both properties match (st) => st.station_name == station.station_name && st.crs_code == station;crs_code ) ) );

You just need to filter the first on basis of second one like this -:

const favouriteArrayMap = favourites.reduce((acc, item) => ({...acc, [item.crs_code]: 1}), {});
const finalArr = favourites.filter(item => !favouriteArrayMap[item.crs_code]);

This is more optimal solution than to use .includes or .some and will run in linear complexity.

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM