Comment vérifier si un élément est dans un tableau

Dans Swift, comment puis-je vérifier si un élément existe dans un tableau? Xcode n'a pas de suggestions pour contain , include , ou has , et une recherche rapide dans le livre n'a rien donné. Une idée de comment le vérifier? Je sais qu'il y a une méthode find qui renvoie le numéro d'index, mais y a-t-il une méthode qui renvoie un booléen comme #include? de ruby ?

exemple de ce dont j'ai besoin:

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

14 réponses

Swift 2, 3, 4:

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

contains() est une méthode d'extension de protocole de SequenceType (pour les séquences d'éléments Equatable ) et non une méthode globale comme dans les versions antérieures.

remarques:

Swift versions plus anciennes:

let elements = [1,2,3,4,5]
if contains(elements, 5) {
    println("yes")
}
718
répondu Martin R 2017-11-04 08:51:04

Pour ceux qui sont venus ici à la recherche d'une trouver et supprimer un objet d'un tableau:

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
répondu DogCoffee 2017-11-04 09:02:54

utiliser cette extension:

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

utiliser comme:

array.contains(1)

mise à jour pour Swift 2/3

notez qu'à partir de Swift 3( ou même 2), l'extension n'est plus nécessaire car la fonction globale contains a été transformée en une paire de méthode d'extension sur Array , ce qui vous permet de faire l'une des deux méthodes suivantes:

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

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

a.contains { "151920920" < 1 }   // => false
55
répondu David Berry 2017-04-05 18:53:11

si vous vérifiez si une instance d'une classe personnalisée ou structure est contenue dans un tableau, vous aurez besoin d'implémenter le protocole Equatable avant de pouvoir l'utiliser .contient(monobjet).

par exemple:

struct Cup: Equatable {
    let filled:Bool
}

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

alors vous pouvez faire:

cupArray.contains(myCup)

Tip : le = = override doit être au niveau global, pas dans votre classe / structure

31
répondu Andrew Schreiber 2017-10-12 18:11:45

j'ai utilisé un filtre.

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

si vous voulez, vous pouvez le compresser en

if elements.filter({ el in el == 5 }).count > 0 {
}

Espère que ça aide.


mise à jour pour Swift 2

Hourray pour les implémentations par défaut!

if elements.contains(5) {
    // any matching items are in results
} else {
    // not found
}
27
répondu Jeffery Thomas 2015-10-13 22:45:14

(Swift 3)

vérifier si un élément existe dans un tableau (répondant à certains critères), et, dans l'affirmative, continuer à travailler avec le premier élément de ce type

si l'intention est:

  1. pour vérifier si un élément existe dans un réseau (/remplit certains critères booléens, pas nécessairement des tests d'égalité),
  2. et si oui, procéder et travailler avec le premier de ces éléments,

puis une alternative à contains(_:) comme un plan Sequence est à first(where:) de Sequence :

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

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

dans cet exemple artificiel, son usage peut sembler stupide, mais il est très utile si vous interrogez des tableaux de types d'éléments non-fondamentaux pour l'existence de n'importe quels éléments remplissant une certaine condition. Par exemple:

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: { "151910920".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: { "151910920".age == daniel.age }) {
    print("\(sameAgeAsDaniel.name) is the same age as \(daniel.name).")
    // ...
} // Sarah is the same age as Daniel.

toute opération enchaînée utilisant .filter { ... some condition }.first peut être remplacée favorablement par first(where:) . Ces derniers montrent une meilleure intention, et ont des avantages de performance sur les appareils non-paresseux possibles de .filter , comme ceux-ci passeront le tableau complet avant d'extraire le (possible) premier élément passant le filtre.


Vérifier si un élément existe dans un tableau (répondant à certains critères), et, si oui, supprimer le premier élément

un commentaire ci-dessous questions:

Comment puis-je supprimer le firstSuchElement du tableau?

un cas d'utilisation similaire à celui ci-dessus est de supprimer le premier élément qui remplit un prédicat donné. Pour ce faire, la index(where:) méthode de Collection (qui est facilement disponible pour le réseau la collecte) peut être utilisée pour trouver l'indice du premier élément répondant au prédicat, après quoi l'indice peut être utilisé avec la remove(at:) méthode de Array pour (possible; étant donné qu'il existe) supprimer cet élément.

var elements = ["a", "b", "c", "d", "e", "a", "b", "c"]

if let indexOfFirstSuchElement = elements.index(where: { "151920920" == "c" }) {
    elements.remove(at: indexOfFirstSuchElement)
    print(elements) // ["a", "b", "d", "e", "a", "b", "c"]
}

ou , si vous souhaitez supprimer l'élément du tableau et travailler avec , appliquer Optional : s map(_:) méthode à conditionnellement (pour .some(...) retour de index(where:) ) utilisez le résultat de index(where:) pour enlever et capturer l'élément retiré du tableau (dans une clause de liaison optionnelle).

var elements = ["a", "b", "c", "d", "e", "a", "b", "c"]

if let firstSuchElement = elements.index(where: { "151930920" == "c" })
    .map({ elements.remove(at: "151930920") }) {

    // 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
}

notez que dans l'exemple contrived ci-dessus les membres du tableau sont des types de valeurs simples ( String instances), donc l'utilisation d'un prédicat pour trouver un membre donné est un peu over-kill, comme nous pourrions simplement tester l'égalité en utilisant la méthode plus simple index(of:) comme montré dans La réponse de @DogCoffee . Si l'on applique l'approche find-and-remove ci-dessus à l'exemple Person , cependant, l'utilisation de index(where:) avec un prédicat est appropriée (puisque nous ne vérifions plus l'égalité mais l'accomplissement d'un prédicat fourni).

14
répondu dfri 2017-05-23 12:26:35

le moyen le plus simple pour accomplir ceci est d'utiliser le filtre sur le tableau.

let result = elements.filter { "151900920"==5 }

result sera l'élément trouvé, s'il existe, et sera vide si l'élément n'existe pas. Donc simplement vérifier si result est vide vous dira si l'élément existe dans le tableau. Je voudrais utiliser le texte suivant:

if result.isEmpty {
    // element does not exist in array
} else {
    // element exists
}
11
répondu davetw12 2015-09-01 15:45:37

comme de Swift 2.1 NSArrays ont containsObject qui peut être utilisé comme ainsi:

if myArray.containsObject(objectImCheckingFor){
    //myArray has the objectImCheckingFor
}
6
répondu ColossalChris 2016-03-21 03:37:47

juste au cas où quelqu'un essaie de trouver si un indexPath est parmi les fonctions sélectionnées (comme dans un UICollectionView ou UITableView cellForItemAtIndexPath ):

    var isSelectedItem = false
    if let selectedIndexPaths = collectionView.indexPathsForSelectedItems() as? [NSIndexPath]{
        if contains(selectedIndexPaths, indexPath) {
            isSelectedItem = true
        }
    }
4
répondu Ali 2014-12-08 15:43:27

voici ma petite extension que je viens d'écrire pour vérifier si mon tableau delegate contient un objet delegate ou non ( Swift 2 ). :) Il fonctionne également avec des types de valeur comme un charme.

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

si vous avez une idée pour optimiser ce code, faites-le moi savoir.

3
répondu DevAndArtist 2017-04-22 09:23:33

Swift

si vous n'utilisez pas object, vous pouvez utiliser ce code pour contains.

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

if elements.contains(50) {

   print("true")

}

si vous utilisez la classe NSObject dans swift. Cette variable est en fonction de mes besoins. vous pouvez modifier pour vos besoins.

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

pour un même type de données.

{ "151920920".user_id == cliectScreenSelectedObject.user_id }

si vous voulez N'importe quel type D'objet.

{ "\("151930920".user_id)" == "\(cliectScreenSelectedObject.user_id)" }

totale de l'état

if cliectScreenSelected.contains( { "151940920".user_id == cliectScreenSelectedObject.user_id } ) == false {

    cliectScreenSelected.append(cliectScreenSelectedObject)

    print("Object Added")

} else {

    print("Object already exists")

 }
2
répondu Anit Kumar 2016-08-02 12:49:41

si l'utilisateur trouve des éléments de tableau particuliers puis utiliser le code ci-dessous même que la valeur entière.

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

 if arrelemnts.contains("test"){
    print("found")   }else{
    print("not found")   }
1
répondu Yogesh shelke 2016-03-03 06:51:56

Swift 4, une autre façon d'atteindre cet objectif, avec la fonction de filtre

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

    if let object = elements.filter({ "151900920" == 5 }).first {
        print("found")
    } else {
        print("not found")
    }
1
répondu Pramod More 2018-06-08 13:10:49

et si on utilisait une table de hachage pour le boulot, comme ça?

d'abord, créer une fonction générique "hash map", étendre le protocole de séquence.

extension Sequence where Element: Hashable {

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

cette extension fonctionnera aussi longtemps que les éléments dans le tableau seront conformes au Hashable, comme les entiers ou les chaînes, voici l'usage...

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

mais pour l'instant, concentrons-nous sur la vérification si l'élément est dans le tableau.

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

print(numExists) // prints true
0
répondu James Rochabrun 2018-06-12 03:52:49