Jak sprawdzić, czy element jest w tablicy

W języku Swift, Jak mogę sprawdzić, czy element istnieje w tablicy? Xcode nie posiada żadnych sugestii dotyczących contain, include, albo has, A Szybkie przeszukanie książki nic nie dało. Jakiś pomysł, jak to sprawdzić? Wiem, że istnieje metoda find, która zwraca numer indeksu, ale czy istnieje metoda, która zwraca wartość logiczną podobną do #include? Rubiego?

Przykład tego, czego potrzebuję:

var elements = [1,2,3,4,5]
if elements.contains(5) {
  //do something
}
 394
Author: emlai, 2014-06-08

14 answers

Swift 2, 3, 4:

let elements = [1, 2, 3, 4, 5]
if elements.contains(5) {
    print("yes")
}

contains() is a protocol extension method of SequenceType (dla sekwencji Equatable elementów), a nie metoda globalna jak w wcześniejsze wydania.

uwagi:

Swift starsze wersje:

let elements = [1,2,3,4,5]
if contains(elements, 5) {
    println("yes")
}
 718
Author: Martin R,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/doraprojects.net/template/agent.layouts/content.php on line 54
2017-11-04 08:51:04

Dla tych, którzy przybyli tutaj szukając znalezienia i usunięcia obiektu z tablicy:

Swift 1

if let index = find(itemList, item) {
    itemList.removeAtIndex(index)
}

Swift 2

if let index = itemList.indexOf(item) {
    itemList.removeAtIndex(index)
}

Swift 3, 4

if let index = itemList.index(of: item) {
    itemList.remove(at: index)
}
 107
Author: DogCoffee,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/doraprojects.net/template/agent.layouts/content.php on line 54
2017-11-04 09:02:54

Użyj tego rozszerzenia:

extension Array {
    func contains<T where T : Equatable>(obj: T) -> Bool {
        return self.filter({$0 as? T == obj}).count > 0
    }
}

Użyj jako:

array.contains(1)

Aktualizacja dla Swift 2/3

Zauważ, że od Swift 3 (lub nawet 2) rozszerzenie nie jest już konieczne, ponieważ funkcja global contains została przekształcona w parę metod rozszerzenia na Array, które pozwalają wykonać jedną z następujących czynności:

let a = [ 1, 2, 3, 4 ]

a.contains(2)           // => true, only usable if Element : Equatable

a.contains { $0 < 1 }   // => false
 55
Author: David Berry,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/doraprojects.net/template/agent.layouts/content.php on line 54
2017-04-05 18:53:11

Jeśli sprawdzasz, czy instancja custom class lub struct jest zawarta w tablicy, musisz zaimplementować Equatable protokół zanim będzie można go użyć .zawiera(myObject).

Na przykład:

struct Cup: Equatable {
    let filled:Bool
}

static func ==(lhs:Cup, rhs:Cup) -> Bool { // Implement Equatable
    return lhs.filled == rhs.filled
}

Wtedy możesz zrobić:

cupArray.contains(myCup)

Wskazówka: nadpisanie = = powinno być na poziomie globalnym, a nie w twojej klasie / strukturze

 31
Author: Andrew Schreiber,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/doraprojects.net/template/agent.layouts/content.php on line 54
2017-10-12 18:11:45

Użyłem filtra.

let results = elements.filter { el in el == 5 }
if results.count > 0 {
    // any matching items are in results
} else {
    // not found
}

Jeśli chcesz, możesz to skompresować do

if elements.filter({ el in el == 5 }).count > 0 {
}
Mam nadzieję, że to pomoże.

Aktualizacja dla Swift 2

Hurra dla domyślnych implementacji!
if elements.contains(5) {
    // any matching items are in results
} else {
    // not found
}
 27
Author: Jeffery Thomas,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/doraprojects.net/template/agent.layouts/content.php on line 54
2015-10-13 22:45:14

(Swift 3)

Sprawdź, czy element istnieje w tablicy (spełniającej pewne kryteria), i jeśli tak, kontynuuj pracę z pierwszym takim elementem

Jeśli intencja jest:

    Aby sprawdzić, czy element istnieje w tablicy (/spełnia pewne kryteria logiczne, niekoniecznie testowanie równości), A jeśli tak, kontynuuj i pracuj z pierwszym takim elementem,

Wtedy alternatywa dla contains(_:) Jak to wygląda w przypadku Sequence first(where:) Z Sequence:

let elements = [1, 2, 3, 4, 5]

if let firstSuchElement = elements.first(where: { $0 == 4 }) {
    print(firstSuchElement) // 4
    // ...
}

W tym wymyślonym przykładzie, jego użycie może wydawać się głupie, ale jest bardzo przydatne, gdy odpytywanie tablic o nie fundamentalne typy elementów o istnienie jakichkolwiek elementów spełniających jakiś warunek. Np.

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.

Dowolne operacje łańcuchowe przy użyciu .filter { ... some condition }.first można zastąpić first(where:). Ta ostatnia pokazuje intencję lepiej i ma przewagę wydajności nad możliwymi nie leniwymi urządzeniami .filter, ponieważ przejdą one pełną tablicę przed ekstrakcją (możliwe) pierwszy element przechodzący przez filtr.


Sprawdź, czy element istnieje w tablicy (spełniającej pewne kryteria), i jeśli tak, usuń pierwszy taki element

Komentarz poniżej zapytań:

Jak mogę usunąć firstSuchElement z tablicy?

Podobny przypadek użycia do powyższego to usunięcie pierwszego elementu spełniającego dany predykat. W tym celu index(where:) metoda Collection (czyli łatwo dostępne do zbioru tablic) mogą być użyte do znalezienia indeksu pierwszego elementu spełniającego predykat, gdzie indeks może być użyty z remove(at:) metoda Array to (possible; give that it exists) usuwa ten element.

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"]
}

Lub, jeśli chcesz usunąć element z tablicy i pracować z, zastosuj Optional: s map(_:) metoda warunkowo (dla .some(...) return from index(where:)) użyj wyniku z index(where:) aby usunąć i przechwycić usunięto element z tablicy (w ramach opcjonalnej klauzuli wiążącej).

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
}

Zauważ, że w wymyślonym przykładzie powyżej członkowie tablicy są prostymi typami wartości( instancjeString), więc użycie predykatu do znalezienia danego elementu jest nieco przesadne, ponieważ możemy po prostu przetestować równość za pomocą prostszej metody index(of:), Jak pokazano w @DogCoffee ' s answer. Jeśli jednak zastosowanie metody znajdź i usuń powyżej do przykładu Person, użycie index(where:) z predykatem jest właściwe (ponieważ nie testujemy już równości, ale spełniamy dostarczony predykat).

 14
Author: dfri,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/doraprojects.net/template/agent.layouts/content.php on line 54
2017-05-23 12:26:35

Najprostszym sposobem na to jest użycie filtra na tablicy.

let result = elements.filter { $0==5 }

result będzie miał znaleziony element, jeśli istnieje i będzie pusty, jeśli element nie istnieje. Tak więc proste sprawdzenie czy {[2] } jest puste powie Ci, czy element istnieje w tablicy. Użyłbym następującego:

if result.isEmpty {
    // element does not exist in array
} else {
    // element exists
}
 11
Author: davetw12,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/doraprojects.net/template/agent.layouts/content.php on line 54
2015-09-01 15:45:37

Od Swift 2.1 NSArrays mają containsObject, które mogą być używane tak:

if myArray.containsObject(objectImCheckingFor){
    //myArray has the objectImCheckingFor
}
 6
Author: ColossalChris,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/doraprojects.net/template/agent.layouts/content.php on line 54
2016-03-21 03:37:47

Na wszelki wypadek, gdyby ktoś próbował znaleźć, czy indexPath jest wśród wybranych (jak w UICollectionView lub UITableView cellForItemAtIndexPath Funkcje):

    var isSelectedItem = false
    if let selectedIndexPaths = collectionView.indexPathsForSelectedItems() as? [NSIndexPath]{
        if contains(selectedIndexPaths, indexPath) {
            isSelectedItem = true
        }
    }
 4
Author: Ali,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/doraprojects.net/template/agent.layouts/content.php on line 54
2014-12-08 15:43:27

Oto moje małe rozszerzenie, które napisałem, aby sprawdzić, czy moja tablica delegatów zawiera obiekt delegata, czy nie (Swift 2 ). :) Działa również z typami wartości jak urok.

extension Array
{
    func containsObject(object: Any) -> Bool
    {
        if let anObject: AnyObject = object as? AnyObject
        {
            for obj in self
            {
                if let anObj: AnyObject = obj as? AnyObject
                {
                    if anObj === anObject { return true }
                }
            }
        }
        return false
    }
}

Jeśli masz pomysł jak zoptymalizować ten kod, daj mi znać.

 3
Author: DevAndArtist,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/doraprojects.net/template/agent.layouts/content.php on line 54
2017-04-22 09:23:33

Swift

Jeśli nie używasz obiektu, możesz użyć tego kodu dla contains.

let elements = [ 10, 20, 30, 40, 50]

if elements.contains(50) {

   print("true")

}

Jeśli używasz klasy NSObject w języku swift. Ta zmienna jest zgodna z moimi wymaganiami. możesz modyfikować do swoich wymagań.

var cliectScreenList = [ATModelLeadInfo]()
var cliectScreenSelectedObject: ATModelLeadInfo!

Jest to dla tego samego typu danych.

{ $0.user_id == cliectScreenSelectedObject.user_id }

Jeśli chcesz typu AnyObject.

{ "\($0.user_id)" == "\(cliectScreenSelectedObject.user_id)" }

Pełny stan

if cliectScreenSelected.contains( { $0.user_id == cliectScreenSelectedObject.user_id } ) == false {

    cliectScreenSelected.append(cliectScreenSelectedObject)

    print("Object Added")

} else {

    print("Object already exists")

 }
 2
Author: Anit Kumar,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/doraprojects.net/template/agent.layouts/content.php on line 54
2016-08-02 12:49:41

Jeśli użytkownik znajdzie określone elementy tablicy, użyj poniższego kodu tak samo jak wartość całkowita.

var arrelemnts = ["sachin", "test", "test1", "test3"]

 if arrelemnts.contains("test"){
    print("found")   }else{
    print("not found")   }
 1
Author: Yogesh shelke,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/doraprojects.net/template/agent.layouts/content.php on line 54
2016-03-03 06:51:56

Swift 4, inny sposób na osiągnięcie tego, z funkcją filtra

Var elements = [1,2,3,4,5]

    if let object = elements.filter({ $0 == 5 }).first {
        print("found")
    } else {
        print("not found")
    }
 1
Author: Pramod More,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/doraprojects.net/template/agent.layouts/content.php on line 54
2018-06-08 13:10:49

A co z użyciem tabeli hash do pracy, jak to?

Po pierwsze, tworzenie funkcji generycznej "hash map", Rozszerzanie protokołu sekwencji.

extension Sequence where Element: Hashable {

    func hashMap() -> [Element: Int] {
        var dict: [Element: Int] = [:]
        for (i, value) in self.enumerated() {
            dict[value] = i
        }
        return dict
    }
}

To rozszerzenie będzie działać tak długo, jak elementy w tablicy są zgodne z Hashable, jak liczby całkowite lub łańcuchy, tutaj jest użycie...

let numbers = Array(0...50) 
let hashMappedNumbers = numbers.hashMap()

let numToDetect = 35

let indexOfnumToDetect = hashMappedNumbers[numToDetect] // returns the index of the item and if all the elements in the array are different, it will work to get the index of the object!

print(indexOfnumToDetect) // prints 35

Ale na razie skupmy się na sprawdzeniu, czy element jest w tablicy.

let numExists = indexOfnumToDetect != nil // if the key does not exist 
means the number is not contained in the collection.

print(numExists) // prints true
 0
Author: James Rochabrun,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/doraprojects.net/template/agent.layouts/content.php on line 54
2018-06-12 03:52:49