我目前有2个数组,一个名为rewardsArray,另一个名为expiredRewardsArray。奖励我是从每次连接时获取的api获得的。 expiredRewardsArray我在本地保存。我试图做的是在viewDidLoad中,在我检索rewardsArray数据后,我想将它与expiredRewardsArray的数据进行比较。如果有匹配,我想从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()
}
}
}
数组中的每个项都有一个id,我用它来查看该项是否在expiredRewardsArray中:
for expiredReward in expiredRewardsArray {
print("This is an expired reward: \(expiredReward.id)")
}
答案 0 :(得分:3)
这是一个使用Set算法的解决方案。因此,它真的很快,但它不会保留元素的排序,它会破坏任何重复。它以线性时间(O(n)
)运行,而天真的方法则为O(n^2)
。
let unexpiredRewards = Set(rewardsArray).subtract(Set(ExpiredRewards))
答案 1 :(得分:2)
for item in expiredRewardsArray {
if let index = rewardsArray.index(of: item) {
//found the item
rewardsArray.remove(at: index)
}
}
这将找到该项并从rewardsArray
中删除它更新:
你说每个项目都有一个id。如果使用上面的代码,if let块永远不会被调用,那么你可以确定这些项目实际上并不相同,或者你没有任何相同的项目。
for itemOne in expiredRewardsArray {
for itemTwo in rewardsArray {
if itemOne.id == itemTwo.id {
rewardsArray.remove(at: index)
}
}
}
性能不是很好,但它能完成任务并保持秩序
答案 2 :(得分:2)
在这种情况下,您应该使用swift方法过滤器。这可以很容易地解决,
func rewardMinusExpired() {
let notExpiredRewards = rewardsArray.filter { a in
return !expiredRewardArray.contains(a)
}
}
答案 3 :(得分:0)
如果expiredRewardsArray
和rewardsArray
是对象数组,那么您需要使用id
属性比较元素来比较它们,而不是indexOf(_:)
。原因是对象是引用类型,因此您可以拥有两个具有相同属性的不同对象,但如果它们不是同一个对象,indexOf(_:)
会将它们视为单独的实体。
请尝试使用此代码:
func rewardsMinusExpired() {
expiredRewardsArray = rewardManager.getExpiredRewards()
rewardsArray = rewardsArray.filter { reward in
let isExpired = expiredRewardsArray.contains { expiredReward in
return expiredReward.id == reward.id
}
return !isExpired
}
}