Swift에서 배열에 요소가 있는지 어떻게 확인할 수 있습니까? 엑스 코드에 대한 어떤 제안이없는 contain
, include
또는 has
, 그리고 책을 통해 빠른 검색은 아무것도를 설정합니다. 이것을 확인하는 방법이 있습니까? find
인덱스 번호를 반환 하는 메서드 가 있지만 ruby와 같은 부울을 반환하는 메서드가 #include?
있습니까?
내가 필요한 것의 예 :
var elements = [1,2,3,4,5]
if elements.contains(5) {
//do something
}
답변
스위프트 2, 3, 4, 5 :
let elements = [1, 2, 3, 4, 5]
if elements.contains(5) {
print("yes")
}
contains()
의 프로토콜 확장 방법 입니다SequenceType
(시퀀스의 Equatable
요소)가 아니라 이전 릴리즈로서 세계 방법.
비고 :
- 이
contains()
방법은 시퀀스 요소가Equatable
프로토콜을 합니다 (예 : Andrews ‘s answer) . - 시퀀스 요소가
NSObject
서브 클래스의 인스턴스 인 경우 재정의해야합니다.isEqual:
참조 == 대 hashValue, ISEQUAL 대 해시 : NSObject의의 스위프트의 서브 클래스를 . contains()
요소가 동일 할 필요가없고 조건으로 인수를 취하는 또 다른보다 일반적인 방법이 있습니다. 예를 들어 Swift의 배열에 객체가 있는지 테스트하는 속기는?.
스위프트 구버전 :
let elements = [1,2,3,4,5]
if contains(elements, 5) {
println("yes")
}
답변
여기에 와서 배열에서 객체를 찾고 제거하는 사람들을 위해 :
스위프트 1
if let index = find(itemList, item) {
itemList.removeAtIndex(index)
}
스위프트 2
if let index = itemList.indexOf(item) {
itemList.removeAtIndex(index)
}
스위프트 3, 4
if let index = itemList.index(of: item) {
itemList.remove(at: index)
}
스위프트 5.2
if let index = itemList.firstIndex(of: item) {
itemList.remove(at: index)
}
답변
이 확장명을 사용하십시오 :
extension Array {
func contains<T where T : Equatable>(obj: T) -> Bool {
return self.filter({$0 as? T == obj}).count > 0
}
}
로 사용:
array.contains(1)
스위프트 2/3 업데이트
Swift 3 (또는 2)부터는 전역 contains
기능이 on의 확장 메소드 쌍으로 만들어져 더 이상 필요하지 않습니다 Array
.
let a = [ 1, 2, 3, 4 ]
a.contains(2) // => true, only usable if Element : Equatable
a.contains { $0 < 1 } // => false
답변
사용자 정의 클래스 또는 구조체 의 인스턴스가 배열에 포함되어 있는지 확인하는 경우 Equatable 을 구현해야합니다. .contains (myObject)를 사용하기 전에 프로토콜 합니다.
예를 들면 다음과 같습니다.
struct Cup: Equatable {
let filled:Bool
}
static func ==(lhs:Cup, rhs:Cup) -> Bool { // Implement Equatable
return lhs.filled == rhs.filled
}
그럼 당신은 할 수 있습니다 :
cupArray.contains(myCup)
팁 : == 재정의는 클래스 / 구조가 아닌 전역 수준에 있어야합니다.
답변
필터를 사용했습니다.
let results = elements.filter { el in el == 5 }
if results.count > 0 {
// any matching items are in results
} else {
// not found
}
원하는 경우 압축하여
if elements.filter({ el in el == 5 }).count > 0 {
}
희망이 도움이됩니다.
스위프트 2 업데이트
기본 구현을위한 Hurray!
if elements.contains(5) {
// any matching items are in results
} else {
// not found
}
답변
(스위프트 3)
요소가 배열에 존재하는지 확인 (일부 기준 충족) 하고있는 경우 첫 번째 요소로 작업을 진행하십시오.
의도가 다음과 같은 경우 :
- 요소가 배열에 존재하는지 확인하려면 (항상 테스트가 아닌 일부 부울 기준을 충족시킵니다),
- 그렇다면 첫 번째 요소로 진행하여 작업하십시오.
그런 다음에 대한 대안 contains(_:)
청사진을로는 Sequence
이다 first(where:)
의 Sequence
:
let elements = [1, 2, 3, 4, 5]
if let firstSuchElement = elements.first(where: { $0 == 4 }) {
print(firstSuchElement) // 4
// ...
}
이 고안된 예에서는 사용법이 어리석은 것처럼 보일 수 있지만 기본 요소가 아닌 요소 유형의 배열에 어떤 조건을 충족시키는 요소가 있는지 쿼리하는 경우 매우 유용합니다. 예 :
struct Person {
let age: Int
let name: String
init(_ age: Int, _ name: String) {
self.age = age
self.name = name
}
}
let persons = [Person(17, "Fred"), Person(16, "Susan"),
Person(19, "Hannah"), Person(18, "Sarah"),
Person(23, "Sam"), Person(18, "Jane")]
if let eligableDriver = persons.first(where: { $0.age >= 18 }) {
print("\(eligableDriver.name) can possibly drive the rental car in Sweden.")
// ...
} // Hannah can possibly drive the rental car in Sweden.
let daniel = Person(18, "Daniel")
if let sameAgeAsDaniel = persons.first(where: { $0.age == daniel.age }) {
print("\(sameAgeAsDaniel.name) is the same age as \(daniel.name).")
// ...
} // Sarah is the same age as Daniel.
사용하는 모든 체인 작업 .filter { ... some condition }.first
은로 대체 할 수 있습니다 first(where:)
. 후자는 의도를 더 잘 나타내고, 가능한 비 게으른 기기에 비해 성능 이점이 있는데 .filter
, 이는 필터를 통과하는 (가능한) 제 1 요소를 추출하기 전에 전체 어레이를 통과하기 때문이다.
요소가 배열에 존재하는지 확인하고 (일부 기준 충족), 존재하는 경우 첫 번째 요소를 제거하십시오
아래의 의견은 다음을 쿼리합니다.
firstSuchElement
어레이에서를 제거하려면 어떻게 해야합니까?
위와 유사한 유스 케이스 는 주어진 술어를 충족시키는 첫 번째 요소 를 제거 하는 것입니다. 이렇게하기 위해, index(where:)
방법 Collection
(배열 컬렉션에 용이하게 사용할 수 있음)의 인덱스가 함께 사용될 수있다 whereafter 술어를 만족 첫번째 요소의 인덱스 찾기 위해 사용될 수있는 remove(at:)
방법 Array
으로 (수를, 주어진이 있는지) 해당 요소를 제거하십시오.
var elements = ["a", "b", "c", "d", "e", "a", "b", "c"]
if let indexOfFirstSuchElement = elements.index(where: { $0 == "c" }) {
elements.remove(at: indexOfFirstSuchElement)
print(elements) // ["a", "b", "d", "e", "a", "b", "c"]
}
또는 배열에서 요소를 제거 하고으로 작업 하려면 Optional
: s map(_:)
메소드를 조건부 (에서 .some(...)
반환 index(where:)
)로 적용하여 결과를 사용 index(where:)
하여 배열에서 제거 된 요소를 제거하고 캡처하십시오 (선택적 바인딩 절 내). .
var elements = ["a", "b", "c", "d", "e", "a", "b", "c"]
if let firstSuchElement = elements.index(where: { $0 == "c" })
.map({ elements.remove(at: $0) }) {
// if we enter here, the first such element have now been
// remove from the array
print(elements) // ["a", "b", "d", "e", "a", "b", "c"]
// and we may work with it
print(firstSuchElement) // c
}
위의 예에서 배열 멤버는 단순한 값 유형 ( String
인스턴스)이므로 주어진 멤버를 찾기 위해 술어를 사용하는 것은 다소 과도합니다 index(of:)
. @ DogCoffee의 답변에 표시된 것처럼 더 간단한 방법을 사용하여 동등성을 테스트 할 수 있기 때문입니다. . Person
그러나 위의 찾기 및 제거 방법을 예제에 적용하는 경우 index(where:)
술어와 함께 사용 하는 것이 적절합니다 (더 이상 동등성을 테스트하지 않고 제공된 술어를 충족시키기 위해).
답변
이를 수행하는 가장 간단한 방법은 배열에서 필터를 사용하는 것입니다.
let result = elements.filter { $0==5 }
result
찾은 요소가 있으면 발견되고 요소가 없으면 비어 있습니다. 따라서 result
비어 있는지 확인하면 요소가 배열에 있는지 여부를 알 수 있습니다. 다음을 사용합니다.
if result.isEmpty {
// element does not exist in array
} else {
// element exists
}