web-dev-qa-db-fra.com

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 aucune suggestion pour contain, include ou has, et une recherche rapide dans le livre n'a révélé aucun résultat. Une idée de comment vérifier cela? Je sais qu'il existe une méthode find qui renvoie le numéro d'index, mais existe-t-il une méthode qui renvoie un booléen tel que #include? de Ruby?

Exemple de ce dont j'ai besoin:

var elements = [1,2,3,4,5]
if elements.contains(5) {
  //do something
}
441
jaredsmith

Swift 2, 3, 4, 5:

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 précédentes.

Remarques:

Swift anciennes versions:

let elements = [1,2,3,4,5]
if contains(elements, 5) {
    println("yes")
}
796
Martin R

Pour ceux qui sont venus ici à la recherche d'une recherche et suppriment 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, 5

if let index = itemList.index(of: item) {
    itemList.remove(at: index)
}
118
DogCoffee

Utilisez cette extension:

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

Utilisé comme:

array.contains(1)

Mise à jour pour Swift 2/

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éthodes d'extension sur Array, qui vous permettent de faire l'un des:

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

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

a.contains { $0 < 1 }   // => false
57
David Berry

Si vous vérifiez si une instance d'un classe ou structure personnalisée est contenue dans un tableau, vous devez implémenter le protocole Équable avant de pouvoir utiliser .contains (myObject ).

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)

Astuce: le remplacement de == devrait se faire au niveau global, pas dans votre classe/structure

36
Andrew Schreiber

J'ai utilisé le 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 compresser cela pour

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

J'espère que ça t'as aidé.


Mise à jour pour Swift 2

Vive les implémentations par défaut!

if elements.contains(5) {
    // any matching items are in results
} else {
    // not found
}
28
Jeffery Thomas

(Swift 3)

Vérifiez si un élément existe dans un tableau (remplissant certains critères), et si oui, continuez avec le premier élément de ce type

Si l'intention est:

  1. Pour vérifier si un élément existe dans un tableau (/ remplit certains critères booléens, pas nécessairement des tests d'égalité),
  2. Et si oui, continuez et travaillez avec le premier élément de ce type,

Ensuite, une alternative à contains(_:) comme Sequence est définie sur first(where:) sur Sequence:

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

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

Dans cet exemple artificiel, son utilisation peut sembler absurde, mais elle est très utile pour interroger des tableaux de types d'éléments non fondamentaux afin de déterminer l'existence d'éléments remplissant certaines conditions. 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: { $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.

Toute opération chaînée utilisant .filter { ... some condition }.first peut être remplacée favorablement par first(where:). Ce dernier montre une meilleure intention et offre des avantages en termes de performances par rapport aux possibles appliances non-paresseuses de .filter, car celles-ci transmettent l'ensemble du tableau avant l'extraction du premier (possible) premier élément transmettant le filtre.


Vérifiez si un élément existe dans un tableau (remplissant certains critères), et si oui, supprimez le premier élément de ce type

Un commentaire sous les requêtes:

Comment puis-je supprimer le firstSuchElement du tableau?

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

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

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

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
}

Notez que dans l'exemple ci-dessus, les membres du tableau sont de simples types de valeur (instances String). L'utilisation d'un prédicat pour trouver un membre donné est donc un peu trop lourde, car nous pourrions simplement tester l'égalité en utilisant la méthode plus simple index(of:), comme indiqué dans - Réponse de @ DogCoffee . Cependant, si vous appliquez la méthode de recherche/suppression ci-dessus à l'exemple Person, il est approprié d'utiliser index(where:) avec un prédicat (car nous ne testons plus l'égalité, mais le respect d'un prédicat fourni).

19
dfri

Le moyen le plus simple d'y parvenir est d'utiliser un filtre sur le tableau.

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

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

if result.isEmpty {
    // element does not exist in array
} else {
    // element exists
}
13
davetw12

À partir de Swift 2.1, les NSArrays ont containsObjectqui peut être utilisé comme suit:

if myArray.containsObject(objectImCheckingFor){
    //myArray has the objectImCheckingFor
}
6
ColossalChris

Juste au cas où quelqu'un essaierait de trouver si une indexPath fait partie des fonctions sélectionnées (comme dans un UICollectionView ou UITableViewcellForItemAtIndexPath fonctions):

    var isSelectedItem = false
    if let selectedIndexPaths = collectionView.indexPathsForSelectedItems() as? [NSIndexPath]{
        if contains(selectedIndexPaths, indexPath) {
            isSelectedItem = true
        }
    }
4
Ali

Voici ma petite extension que je viens d'écrire pour vérifier si mon tableau de délégués contient un objet délégué ou non (Swift 2). :) Il fonctionne également avec les 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 sur la façon d'optimiser ce code, faites-le moi savoir.

3
DevAndArtist

Swift 4, une autre façon d'y parvenir, avec la fonction de filtrage

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

    if let object = elements.filter({ $0 == 5 }).first {
        print("found")
    } else {
        print("not found")
    }
3
Pramod More

Tableau

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

Vérifier la présence d'éléments

elements.contains(5) // true

Obtenir l'index des éléments

elements.firstIndex(of: 5) // 4
elements.firstIndex(of: 10) // nil

Obtenir le nombre d'éléments

let results = elements.filter { element in element == 5 }
results.count // 2
3

si l'utilisateur trouve des éléments de tableau particuliers, utilisez le code ci-dessous identique à la valeur entière.

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

 if arrelemnts.contains("test"){
    print("found")   }else{
    print("not found")   }
2
Yogesh shelke

Swift

Si vous n'utilisez pas d'objet, vous pouvez utiliser ce code pour contient.

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

if elements.contains(50) {

   print("true")

}

Si vous utilisez NSObject Class dans Swift. Cette variable est en fonction de mes besoins. vous pouvez modifier pour votre exigence.

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

Ceci est pour un même type de données.

{ $0.user_id == cliectScreenSelectedObject.user_id }

Si vous voulez tout type AnyObject.

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

État complet

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

    cliectScreenSelected.append(cliectScreenSelectedObject)

    print("Object Added")

} else {

    print("Object already exists")

 }
2
Anit Kumar

qu'en est-il d'utiliser une table de hachage pour le travail, comme celui-ci?

tout d'abord, créer une fonction générique "hash map", étendant 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 du tableau seront conformes à Hashable, comme des entiers ou des chaînes, voici l'utilisation ...

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 pour vérifier 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
1
James Rochabrun

Swift 4.2 +
Vous pouvez facilement vérifier que votre instance est un tableau ou non à l’aide de la fonction suivante.

 func verifyIsObjectOfAnArray<T>(_ object: T) -> Bool {
        if let _ = object as? [T] {
            return true
        }
        return false
    } . 

Même vous pouvez y accéder comme suit. Vous recevrez Nil si l'objet ne serait pas un tableau.

 func verifyIsObjectOfAnArray<T>(_ object: T) -> [T]? {
    if let array = object as? [T] {
        return array
    }
    return nil
}
0
Kiran Jasvanee