2016-05-03 7 views
2

ボタンをクリックするとstockSymbolの値と同じNSUserDefaultsの要素を削除しようとしました。私の考えは、NSUserDefaultsを配列にキャストし、removeAtIndexで要素を削除することです。ここに私のコードです。removeAtIndexでSwiftのインデックスが範囲外になっています

@IBAction func buttonFilledStarClicked(sender: AnyObject) { 
    NSLog("Filled star clicked") 
    self.buttonFilledStar.hidden = true 
    self.buttonEmptyStar.hidden = false 

    var Array = NSUserDefaults.standardUserDefaults().objectForKey("favorites")! as! [String] 
    var countArray = (NSUserDefaults.standardUserDefaults().objectForKey("favorites")! as! [String]).count - 1 


    for i in 0...countArray { 
     if stockSymbol! == Array[i] { 
      NSLog("i is : \(i)") 
      Array.removeAtIndex(i) 
     } 
     else {} 
    } 

    NSLog("Array is: \(Array), countArray is: \(countArray)") 

} 

ただし、「インデックス外です」というエラーがあります。 私はちょうどArray.removeAtIndex(i)をコメントアウトすると動作します。 配列は次のようになります。 ["aa"、 "bb"、 "Test!"、 "Test!"] 提案がありますか?前もって感謝します。

+0

あなたは後ろから前に繰り返す必要があります。 – nhgrif

答えて

2

removeAtIndex(i)を呼び出すときにループの内側から削除してはいけません。Arrayは項目を削除してcountArrayを減らします。したがって、必要な項目を覚えておく別の配列が必要ですだから、フィルタ

// Filter only strings that match stockSymbol 
Array = Array.filter { $0 == stockSymbol! } 
2

あなたがindex out of rangeという結果をもたらすiを見つけようとしてください。それは0か最後のものですか?たぶんあなたは他の役に立つ手がかりを見つけるでしょう。

3

を使用することで削除し、削除し、それをループの外に...またはより良いオプション、あなたが全体的に自分のコードに最も影響してエラーを解決するために作ることができるの変化は、単にを反復処理するだろう後方インデックス:

for i in (0...countArray).reverse() { 
    if stockSymbol! == Array[i] { 
     NSLog("i is : \(i)") 
     Array.removeAtIndex(i) 
    } 
    else {} 
} 

しかし、のは、簡単な例を見てみましょう...

Array = Array.filter { $0 != stockSymbol } 

クラッシュが起こっている理由について、拡張ノートを

:最良のオプションは、ちょうどスウィフトのfilterを使用することです。

var arr = [1, 2, 3, 4, 5, 6, 7, 8, 9, 10] 

そして、私はそれのうち奇数のすべてを削除する:言って私はarray次持っています。あなたの最初の単純なアプローチを使用して、私はこのような論理を書くかもしれません:

for i in 0..<arr.count { 
    if arr[i] % 2 != 0 { 
     arr.removeAtIndex(i) 
    } 
} 

各繰り返しで何が起こるかを見てください。

最初の反復では、arr[i]1です。これは奇数であるので、我々はremoveAtIndexよ、と私たちの配列は今、実際に次のようになります。

[2, 3, 4, 5, 6, 7, 8, 9, 10] 

配列のサイズが今より小さくある - それだけで9つの要素を持っています。しかし、ループは古いCスタイルのループのようには機能しません。ここでは、i < arr.countが各繰り返しでチェックされます(これはなぜこのループが速いのかの一部です)。

しかし、我々は前方反復時に起こる何かを気づく... 2回目の反復で

i1に等しく、だから何arr[i]は、私たちを与えるのでしょうか?それは私達に3を与える。我々は決して2をチェックすることはありません。第1の反復において、i0であるとき、それはインデックス1であった。第2の反復において、i1である場合、2は、インデックス0である。

したがって、2回目の繰り返しでは、をiとし、1とし、3を削除します。

私達はちょうど偶数の私達の配列で終わるまで、このパターンは数回の反復のために継続されます:

[2, 4, 6, 8, 10] 
をしかし、これは i4に等しかった繰り返しの後に発生し、ループをしようとしています i10に等しいまで実行してみてください。

ループの6番目の反復で、配列のインデックス5にある要素にアクセスしようとします。しかし配列には5つの要素しかないので、最大のインデックスは4です。インデックス5にアクセスしようとすると、クラッシュします。

0

すべての配列の最初の型である、多分あなたが呼び出すことができます。

var favourites = NSUserDefaults.standardUserDefaults().objectForKey("favorites")! as! [String] 

を次にあなたがカウント配列プロパティを使用してアクセスすることができ、アレイのカウント変数は必要ありません。最後に

あなたは、配列を反復処理し、それは常にインデックスが始まりと同じではありませんので、「インデックスのエラー」をスローする予定の要素を削除している場合..

これを解決するために、あなたは、の二つのポインタを取ることができますインデックス変数ですが、私がやることは次のようなものです:

var correctElements = favourites.filter({$0!=stockSymbol}) 
関連する問題