[arrays] 요소가 배열에 있는지 확인하는 방법

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요소)가 아니라 이전 릴리즈로서 세계 방법.

비고 :

스위프트 구버전 :

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)

요소가 배열에 존재하는지 확인 (일부 기준 충족) 하고있는 경우 첫 번째 요소로 작업을 진행하십시오.

의도가 다음과 같은 경우 :

  1. 요소가 배열에 존재하는지 확인하려면 (항상 테스트가 아닌 일부 부울 기준을 충족시킵니다),
  2. 그렇다면 첫 번째 요소로 진행하여 작업하십시오.

그런 다음에 대한 대안 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
}