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 rien révélé. Une idée de comment vérifier cela? Je sais qu’il existe une méthode de find qui renvoie le numéro d’index, mais existe-t-il une méthode qui retourne un booléen comme #include? ?

Exemple de ce dont j’ai besoin:

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

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

Remarques:

  • Cette méthode contains() nécessite que les éléments de séquence adoptent le protocole Equatable , comparez par exemple la réponse d’Andrews .
  • Si les éléments de séquence sont des instances d’une sous-classe NSObject vous devez remplacer isEqual: voir la sous-classe NSObject dans Swift: hash vs hashValue, isEqual vs == .
  • Il existe une autre méthode – plus générale – contains() qui n’exige pas que les éléments soient équitables et prenne un prédicat comme argument, voir par exemple: Shorthand pour tester si un object existe dans un tableau pour Swift? .

Swift anciennes versions:

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

Pour ceux qui sont venus ici chercher une trouvaille et supprimer un object d’un tableau:

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

Utilisez cette extension:

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

Utilisé comme:

 array.contains(1) 

Mis à 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 global contains a été transformée en une paire de méthodes d’extension sur Array , ce qui vous permet d’effectuer l’une des opérations suivantes:

 let a = [ 1, 2, 3, 4 ] a.contains(2) // => true, only usable if Element : Equatable a.contains { $0 < 1 } // => false 

Si vous vérifiez si une instance d’une classe ou d’une structure personnalisée est contenue dans un tableau, vous devez implémenter le protocole Equatable 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 == doit être au niveau global, pas dans votre classe / struct

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 le compresser pour

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

J’espère que cela pourra aider.


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 } 

(Swift 3)

Vérifier si un élément existe dans un tableau (répondant à certains critères), et si oui, 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 tableau (/ remplit certains critères booléens, pas nécessairement des tests d’égalité),
  2. Et si oui, procéder et travailler avec le premier élément,

Ensuite, une alternative à contains(_:) comme Blueprinted Sequence consiste à d’ first(where:) of 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 idiote, mais elle est très utile si vous interrogez des tableaux de types d’éléments non fondamentaux pour détecter la présence d’éléments remplissant certaines conditions. Par exemple

 struct Person { let age: Int let name: Ssortingng init(_ age: Int, _ name: Ssortingng) { 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 en chaîne utilisant .filter { ... some condition }.first peut être remplacée favorablement par first(where:) . Ce dernier montre une intention meilleure et présente des avantages en .filter de performances par rapport aux éventuels appareils non paresseux de .filter , car ceux-ci transmettent l’intégralité du tableau avant d’extraire le premier élément (possible) passant le filtre.


Vérifier si un élément existe dans un tableau (répondant à certains critères) et, si tel est le cas, supprimer le premier élément de ce type

Un commentaire ci-dessous:

Comment puis-je supprimer 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 d’ index(where:) de Collection (qui est facilement disponible pour la collection de tableaux) peut être utilisée pour rechercher l’index du premier élément remplissant le prédicat, après quoi l’index peut être utilisé avec la commande remove(at:) méthode de Array à (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: { $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 Optional : s map(_:) méthode à conditionnelle (pour .some(...) retourne de l’ index(where:) ) utilise le résultat from 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 des types de valeur simples (instances Ssortingng ). L’utilisation d’un prédicat pour trouver un membre donné est donc quelque peu exagérée, car nous pourrions simplement tester l’égalité en utilisant la méthode d’ index(of:) plus simple comme indiqué dans la réponse de @ DogCoffee . Si vous appliquez la méthode de recherche et de suppression ci-dessus à l’exemple Person , cependant, l’utilisation d’ index(where:) avec un prédicat est appropriée (car nous ne testons plus l’égalité mais remplissons un prédicat fourni).

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

À partir de Swift 2.1, NSArrays containsObject qui peut être utilisé comme suit:

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

Juste au cas où quelqu’un indexPath trouver si un indexPath fait partie des éléments sélectionnés (comme dans les fonctions UICollectionView ou UITableView cellForItemAtIndexPath ):

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

Voici ma petite extension que je viens d’écrire pour vérifier si mon tableau de délégué contient un object 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 de comment optimiser ce code, faites-le moi savoir.

Rapide

Si vous n’utilisez pas d’object, 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 selon 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 le type AnyObject.

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

Condition complète

 if cliectScreenSelected.contains( { $0.user_id == cliectScreenSelectedObject.user_id } ) == false { cliectScreenSelected.append(cliectScreenSelectedObject) print("Object Added") } else { print("Object already exists") } 

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

Swift 4, une autre façon d’y parvenir, avec la fonction de filtre

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

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

Qu’en est-il de l’utilisation d’une table de hachage pour le travail, comme ça?

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 tant que les éléments du tableau sont conformes à Hashable, comme les entiers ou les 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 simplement 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