[swift] 스위프트 배열-인덱스가 있는지 확인

Swift에서 치명적인 오류가 발생하지 않고 배열에 인덱스가 있는지 확인하는 방법이 있습니까?

나는 이런 식으로 할 수 있기를 바랐다.

let arr: [String] = ["foo", "bar"]
let str: String? = arr[1]
if let str2 = arr[2] as String? {
    // this wouldn't run
    println(str2)
} else {
    // this would be run
}

그러나 나는 얻는다

치명적인 오류 : 배열 인덱스가 범위를 벗어남



답변

스위프트의 우아한 방법 :

let isIndexValid = array.indices.contains(index)


답변

타입 확장 :

extension Collection {

    subscript(optional i: Index) -> Iterator.Element? {
        return self.indices.contains(i) ? self[i] : nil
    }

}

이것을 사용하면 선택적 키워드를 색인에 추가 할 때 선택적 값을 얻을 수 있습니다. 이는 색인이 범위를 벗어난 경우에도 프로그램이 충돌하지 않음을 의미합니다. 귀하의 예에서 :

let arr = ["foo", "bar"]
let str1 = arr[optional: 1] // --> str1 is now Optional("bar")
if let str2 = arr[optional: 2] {
    print(str2) // --> this still wouldn't run
} else {
    print("No string found at that index") // --> this would be printed
}


답변

인덱스가 배열 크기보다 작은 지 확인하십시오.

if 2 < arr.count {
    ...
} else {
    ...
}


답변

확장 설탕을 추가하십시오 :

extension Collection {
  subscript(safe index: Index) -> Iterator.Element? {
    guard indices.contains(index) else { return nil }
    return self[index]
  }
}

if let item = ["a", "b", "c", "d"][safe: 3] { print(item) }//Output: "d"
//or with guard:
guard let anotherItem = ["a", "b", "c", "d"][safe: 3] else {return}
print(anotherItem) // "d"

if let배열과 함께 스타일 코딩을 수행 할 때 가독성 향상


답변

배열의 크기를 확인하기 위해 더 안전한 방법으로 이것을 다시 작성하고 삼항 조건을 사용할 수 있습니다.

if let str2 = (arr.count > 2 ? arr[2] : nil) as String?


답변

스위프트 4 확장 :

나를 위해 나는 같은 방법을 선호합니다.

// MARK: - Extension Collection

extension Collection {

    /// Get at index object
    ///
    /// - Parameter index: Index of object
    /// - Returns: Element at index or nil
    func get(at index: Index) -> Iterator.Element? {
        return self.indices.contains(index) ? self[index] : nil
    }
}

@ Benno Kress 덕분에


답변

배열 인덱스가 존재하는지 확인 :

이 방법은 확장 설탕을 추가하지 않으려는 경우에 좋습니다.

let arr = [1,2,3]
if let fourthItem = (3 < arr.count ?  arr[3] : nil ) {
     Swift.print("fourthItem:  \(fourthItem)")
}else if let thirdItem = (2 < arr.count ?  arr[2] : nil) {
     Swift.print("thirdItem:  \(thirdItem)")
}
//Output: thirdItem: 3