2016-08-10 6 views
1

私は現在、2つの配列、1つはrewardsArray、もう1つはexpiredRewardsArrayを持っています。 rewardsArray私は接続するたびに取得されたAPIから取得しています。 expiredRewardsArray私はローカルに保存します。私がしようとしているのは、私がexpiredRewardsArrayのデータと比較したいrewardsArrayデータを取得した後に、viewDidLoadにあることです。一致するものがある場合は、rewardsArrayからアイテムを削除します。これは私がこれまで持っているものですが、それはrewardsArrayから項目を削除していないので、括弧「許可すれば」内には行くことはありません:2つの配列が同じ要素を持っているかどうかを確認する方法と、同じ要素が配列の1つから削除されている場合はどうすればいいですか?

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

は重要な要素の順序ですか? – Alexander

+0

が報酬の配列にあります。期限が切れた報酬の配列ではありません – SwiftyJD

+0

ああ、私はちょうど順序が問題ではない解決策を投稿しました=/ – Alexander

答えて

0

を解決することができ、その後はむしろindexOf(_:)よりも、それらを比較するために彼らのidプロパティを使用して要素を比較する必要があります。これは、オブジェクトが参照型であるため、同一のプロパティを持つ2つの異なるオブジェクトを持つことができますが、同じオブジェクトでない場合、indexOf(_:)はそれらを別々のエンティティとして扱います。

は、代わりにこのコードを試してみてください。

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

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

これを試してみると、フィルタ部分をジャンプします – SwiftyJD

+0

...非常に奇妙な。問題のコンテキストに関する情報をさらに提供できますか? –

+0

私はカスタムクラスをclass-MemberRewardsInfoという型として持っています:NSObject、Mappable、NSCoding、これに影響しますか? – SwiftyJD

2
for item in expiredRewardsArray { 
    if let index = rewardsArray.index(of: item) { 
     //found the item 
     rewardsArray.remove(at: index) 
    } 
} 

このアイテムを見つけ、

UPDATE rewardsArrayからそれを削除します:

各アイテムにはIDがあるとします。上記のコードでif letブロックが呼び出されない場合、アイテムが実際に同じでないか、等しいアイテムがないことを確かめることができます。

for itemOne in expiredRewardsArray { 
    for itemTwo in rewardsArray { 
     if itemOne.id == itemTwo.id { 
      rewardsArray.remove(at: index) 
     } 
    } 
} 

あまりパフォーマンスが、それはその仕事をして、オーダー

+0

これを試してみましたが、 "if let index"括弧の中には入りません – SwiftyJD

+0

答えが – Yannick

3

ここで設定した算術演算を使用するソリューションだを保持します。結果として、それは本当に速いですが、要素の順序を保持することはなく、重複するものはすべて破棄されます。これは線形時間(O(n))で実行されますが、単純なアプローチはO(n^2)になります。

let unexpiredRewards = Set(rewardsArray).subtract(Set(ExpiredRewards)) 
+0

更新されました。これはうまくいきません。 – SwiftyJD

+1

'Set'はオブジェクトの等価性を判断するために[' Equatable'](https://developer.apple.com/library/ios/documentation/Swift/Reference/Swift_Equatable_Protocol/index.html)を使用します。そのプロトコルに準拠し、 '=='を実装して、 '$ 0.id == $ 1.id'の2つの' Reward'インスタンスが等しくなるようにします。 – Alexander

2

このような場合は、実際には迅速なフィルタを使用する必要があります。 expiredRewardsArrayrewardsArrayは、オブジェクトの配列の場合、これは簡単に、このよう

func rewardMinusExpired() { 
    let notExpiredRewards = rewardsArray.filter { a in 
     return !expiredRewardArray.contains(a) 
    } 
} 
関連する問題