简体   繁体   中英

How to compare two arrays of objects and only remove items from 1st array if 2nd arrays item value says so

I'm trying to create a new array of objects by comparing 2 existing ones. I want to only return items that pass the if statement.

I want this to happen: If the item name from the addedArray matches the item name from mainArray AND the "added" values are the same then return the item to the new array, OR if the item names don't match, add the item to the new array anyways.

If this doesn't make sense, please look at the result that I want.

Here is what I have right now and for some reason, the new array still has all the items of addedArray. I don't understand why.

 const mainArray = [ {name: 'item1', added: false}, {name: 'item2', added: true}, {name: 'item3', added: false} ] const addedArray = [ {name: 'item2', added: true}, {name: 'item3', added: true}, {name: 'item5', added: true} ] let newAddedArray = addedArray.filter((addedItem) => { return mainArray.map((mainItem) => { if ((addedItem.name === mainItem.name && addedItem.added === mainItem.added) || addedItem.name !== mainItem.name) { return { ...addedItem, addedItem } } }) }) // Result I want // newAddedArray = [ // {name: 'item2', added: true}, // {name: 'item5', added: true} // ] console.log(newAddedArray)

Try like below,

let newAddedArray = [];
    mainArray.forEach((main) => {
        newAddedArray = addedArray.filter((added) => {
            return ((added.name === main.name && added.added === main.added) || added.name !== main.name);
        });
    });

The second condition in the OR passes for all the items in the addedArray. So, you're seeing all items in your result.

From the result you're expecting, it is clear that you're trying to skip any item from mainArray that has 'added' value unmatched with that in addedArray. Try the following

addedArray.filter(function(addedItem){
    const itemFromMain = mainArray.find(function(mainItem){
        return mainItem.name === addedItem.name;
    });
    // If mainItem is found and 'added' matches or if mainItem is not found, accept it
    if(!itemFromMain || (itemFromMain && itemFromMain.added === addedItem.added)) return true;
    return false;
});

Please note that the "find" method on Array is not supported on IE. https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Array/find

Edit : You can also have this condition to simplify

if(itemFromMain && itemFromMain.added !== addedItem.added) return false;
return true;

You can use array .some for this one, modifying your filter function:

 const mainArray = [ {name: 'item1', added: false}, {name: 'item2', added: true}, {name: 'item3', added: false} ] const addedArray = [ {name: 'item2', added: true}, {name: 'item3', added: true}, {name: 'item5', added: true} ] let newAddedArray = addedArray.filter(item => { const { name, added } = item; return mainArray.some(arr => arr.added && added && arr.name == name) || !mainArray.some(arr => arr.name === name) }) console.log(newAddedArray)

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