SwiftyJD SwiftyJD - 3 months ago 15
Swift Question

How to check if 2 arrays have the same element and if it does, delete that element from one of the arrays?

I currently have 2 arrays, one called rewardsArray and one called expiredRewardsArray. The rewardsArray I'm getting from an api thats fetched every time I connect. The expiredRewardsArray I save locally. What I'm trying to do is in the viewDidLoad, after I retrieve the rewardsArray data I want to compare it to the expiredRewardsArray's data. If there is a match I want to remove the item from the rewardsArray. This is what I have so far but it never goes inside the "if let" brackets so it's not removing the item from the rewardsArray:

func rewardsMinusExpired () {

expiredRewardsArray = rewardManager.getExpiredRewards()

for expiredReward in expiredRewardsArray {
if let ex = rewardsArray.indexOf(expiredReward){

print("Expired Reward to be removed: \(ex)")

rewardsArray.removeAtIndex(ex)

rewardsTableView.reloadData()
}
}
}


Each item in the array has an id, I use that to see if the item is in the expiredRewardsArray:

for expiredReward in expiredRewardsArray {
print("This is an expired reward: \(expiredReward.id)")
}

Answer

If expiredRewardsArray and rewardsArray are arrays of objects, then you'll need to compare the elements using their id property to compare them, rather than indexOf(_:). The reason for this is that objects are reference types, so you can have two different objects with identical properties, but if they're not the same object, indexOf(_:) will treat them as separate entities.

Try this code instead:

func rewardsMinusExpired() {
    expiredRewardsArray = rewardManager.getExpiredRewards()

    rewardsArray = rewardsArray.filter { reward in
        let isExpired = expiredRewardsArray.contains { expiredReward in
            return expiredReward.id == reward.id
        }
        return !isExpired
    }
}
Comments