オプションバインディングを介して、Swift で安全な (境界チェックされた) 配列検索を行うには? 質問する

オプションバインディングを介して、Swift で安全な (境界チェックされた) 配列検索を行うには? 質問する

Swift に配列があり、範囲外のインデックスにアクセスしようとすると、予想どおりランタイム エラーが発生します。

var str = ["Apple", "Banana", "Coconut"]

str[0] // "Apple"
str[3] // EXC_BAD_INSTRUCTION

しかし、Swift が提供するすべてのオプション チェーンと安全性を考慮すると、次のようなことは簡単にできると思います。

let theIndex = 3
if let nonexistent = str[theIndex] { // Bounds check + Lookup
    print(nonexistent)
    ...do other things with nonexistent...
}

の代わりに:

let theIndex = 3
if (theIndex < str.count) {         // Bounds check
    let nonexistent = str[theIndex] // Lookup
    print(nonexistent)   
    ...do other things with nonexistent... 
}

しかし、そうではありません。古いifステートメントを使用して、インデックスが 未満であることを確認しなければなりませんstr.count

独自のsubscript()実装を追加しようとしましたが、元の実装に呼び出しを渡す方法や、添え字表記を使用せずに項目 (インデックスベース) にアクセスする方法がわかりません。

extension Array {
    subscript(var index: Int) -> AnyObject? {
        if index >= self.count {
            NSLog("Womp!")
            return nil
        }
        return ... // What?
    }
}

ベストアンサー1

アレックスの答え質問に対する良いアドバイスと解決策がありますが、私は偶然この機能を実装するより良い方法を見つけました:

extension Collection {
    /// Returns the element at the specified index if it is within bounds, otherwise nil.
    subscript (safe index: Index) -> Element? {
        return indices.contains(index) ? self[index] : nil
    }
}

let array = [1, 2, 3]

for index in -20...20 {
    if let item = array[safe: index] {
        print(item)
    }
}

おすすめ記事