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
}
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:
- cette méthode
contains()
exige que les éléments de séquence adopter laEquatable
, comparez par exemple Andrews answer . - si les éléments de séquence sont des instances d'une sous-classe
NSObject
ensuite, vous devez remplacerisEqual:
, voir NSObject subclass dans Swift: hash vs hashValue, isEqual vs = = . - il y a une autre méthode – plus générale -
contains()
qui n'exige pas que les éléments soient égalisables et prend un prédicat comme un argument, voir par ex. Raccourci pour tester si un objet existe dans un tableau pour Swift? .
Swift versions plus anciennes:
let elements = [1,2,3,4,5]
if contains(elements, 5) {
println("yes")
}
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)
}
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
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
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
}
(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:
- 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é),
- 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).
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
}
comme de Swift 2.1 NSArrays ont containsObject
qui peut être utilisé comme ainsi:
if myArray.containsObject(objectImCheckingFor){
//myArray has the objectImCheckingFor
}
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
}
}
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.
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")
}
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") }
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")
}
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