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