J'essaie de trouver un index d'articles en recherchant une liste. Est-ce que quelqu'un sait comment faire ça?
Je vois qu'il y a list.StartIndex
et list.EndIndex
mais je veux quelque chose comme le list.index("text")
de python.
Comme Swift est à certains égards plus fonctionnel que l’objet orienté (et que les tableaux sont des structures, pas des objets), utilisez la fonction "find" pour agir sur le tableau, ce qui retourne une valeur optionnelle. gérer une valeur nulle:
let arr:Array = ["a","b","c"]
find(arr, "c")! // 2
find(arr, "d") // nil
Mise à jour pour Swift 2.0:
L'ancienne fonction find
n'est plus supportée avec Swift 2.0!
Avec Swift 2.0, Array
permet de rechercher l'index d'un élément à l'aide d'une fonction définie dans une extension de CollectionType
(que Array
implémente):
let arr = ["a","b","c"]
let indexOfA = arr.indexOf("a") // 0
let indexOfB = arr.indexOf("b") // 1
let indexOfD = arr.indexOf("d") // nil
De plus, la recherche du premier élément d'un tableau remplissant un prédicat est prise en charge par une autre extension de CollectionType
:
let arr2 = [1,2,3,4,5,6,7,8,9,10]
let indexOfFirstGreaterThanFive = arr2.indexOf({$0 > 5}) // 5
let indexOfFirstGreaterThanOneHundred = arr2.indexOf({$0 > 100}) // nil
Notez que ces deux fonctions renvoient des valeurs optionnelles, comme find
.
Mise à jour pour Swift 3.0:
Notez que la syntaxe de indexOf a changé. Pour les articles conformes à Equatable
, vous pouvez utiliser:
let indexOfA = arr.index(of: "a")
Une documentation détaillée de la méthode est disponible à l’adresse suivante: https://developer.Apple.com/reference/Swift/array/1689674-index
Pour les éléments de tableau non conformes à Equatable
, vous devrez utiliser index(where:)
:
let index = cells.index(where: { (item) -> Bool in
item.foo == 42 // test if this is the item you're looking for
})
Mise à jour pour Swift 4.2:
Avec Swift 4.2, index
n'est plus utilisé, mais est séparé en firstIndex
et lastIndex
pour une meilleure clarification. Donc, selon que vous recherchiez le premier ou le dernier index de l’article:
let arr = ["a","b","c","a"]
let indexOfA = arr.firstIndex(of: "a") // 0
let indexOfB = arr.lastIndex(of: "a") // 3
tl; dr:
Pour les cours, vous recherchez peut-être:
let index = someArray.firstIndex{$0 === someObject}
Réponse complète:
Je pense qu'il vaut la peine de mentionner qu'avec les types de référence (class
), vous pouvez effectuer une comparaison d'identité , auquel cas vous devez simplement utilisez l'opérateur d'identité ===
dans la fermeture du prédicat:
Swift 5, Swift 4.2:
let person1 = Person(name: "John")
let person2 = Person(name: "Sue")
let person3 = Person(name: "Maria")
let person4 = Person(name: "Loner")
let people = [person1, person2, person3]
let indexOfPerson1 = people.firstIndex{$0 === person1} // 0
let indexOfPerson2 = people.firstIndex{$0 === person2} // 1
let indexOfPerson3 = people.firstIndex{$0 === person3} // 2
let indexOfPerson4 = people.firstIndex{$0 === person4} // nil
Notez que la syntaxe ci-dessus utilise la syntaxe de fermeture finale et équivaut à:
let indexOfPerson1 = people.firstIndex(where: {$0 === person1})
Swift 4/Swift 3 - cette fonction s'appelait auparavant index
Swift 2 - la fonction s'appelait auparavant indexOf
* Notez le pertinent et utile commentaire par paulbailey à propos de class
types qui implémentent Equatable
, où vous devez envisager la possibilité de comparer en utilisant ===
(( opérateur d'identité ) ou ==
( égalité opérateur). Si vous décidez de faire correspondre en utilisant ==
, alors vous pouvez simplement utiliser la méthode suggérée par d'autres (people.firstIndex(of: person1)
).
Vous pouvez filter
un tableau avec une fermeture:
var myList = [1, 2, 3, 4]
var filtered = myList.filter { $0 == 3 } // <= returns [3]
Et vous pouvez compter un tableau:
filtered.count // <= returns 1
Ainsi, vous pouvez déterminer si un tableau inclut votre élément en combinant ces éléments:
myList.filter { $0 == 3 }.count > 0 // <= returns true if the array includes 3
Si vous voulez trouver le poste, je ne vois pas les moyens fantaisistes, mais vous pouvez certainement le faire comme ceci:
var found: Int? // <= will hold the index if it was found, or else will be nil
for i in (0..x.count) {
if x[i] == 3 {
found = i
}
}
EDIT
Pendant que nous y sommes, pour un exercice amusant, étendons Array
pour avoir une méthode find
:
extension Array {
func find(includedElement: T -> Bool) -> Int? {
for (idx, element) in enumerate(self) {
if includedElement(element) {
return idx
}
}
return nil
}
}
Maintenant nous pouvons faire ceci:
myList.find { $0 == 3 }
// returns the index position of 3 or nil if not found
func firstIndex(of element: Element) -> Int?
var alphabets = ["A", "B", "E", "D"]
Exemple 1
let index = alphabets.firstIndex(where: {$0 == "A"})
Exemple2
if let i = alphabets.firstIndex(of: "E") {
alphabets[i] = "C" // i is the index
}
print(alphabets)
// Prints "["A", "B", "C", "D"]"
Bien que indexOf()
fonctionne parfaitement, il ne retourne qu'un index.
Je recherchais un moyen élégant d’obtenir un tableau d’index pour des éléments satisfaisant certaines conditions.
Voici comment cela peut être fait:
Swift 3:
let array = ["Apple", "dog", "log"]
let indexes = array.enumerated().filter {
$0.element.contains("og")
}.map{$0.offset}
print(indexes)
Swift 2:
let array = ["Apple", "dog", "log"]
let indexes = array.enumerate().filter {
$0.element.containsString("og")
}.map{$0.index}
print(indexes)
Pour la classe personnalisée, vous devez implémenter le protocole Equatable.
import Foundation
func ==(l: MyClass, r: MyClass) -> Bool {
return l.id == r.id
}
class MyClass: Equtable {
init(id: String) {
self.msgID = id
}
let msgID: String
}
let item = MyClass(3)
let itemList = [MyClass(1), MyClass(2), item]
let idx = itemList.indexOf(item)
printl(idx)
Mise à jour pour Swift 2:
sequence.contains (element): Renvoie true si une séquence donnée (telle qu'un tableau) contient l'élément spécifié.
Swift 1:
Si vous cherchez seulement à vérifier si un élément est contenu dans un tableau, c’est-à-dire, obtenez un indicateur booléen, utilisez contains(sequence, element)
au lieu de find(array, element)
:
contient (sequence, element): Renvoie true si une séquence donnée (telle qu'un tableau) contient l'élément spécifié.
Voir exemple ci-dessous:
var languages = ["Swift", "Objective-C"]
contains(languages, "Swift") == true
contains(languages, "Java") == false
contains([29, 85, 42, 96, 75], 42) == true
if (contains(languages, "Swift")) {
// Use contains in these cases, instead of find.
}
Swift 4. Si votre tableau contient des éléments de type [String: AnyObject]. Donc, pour trouver l'index de l'élément, utilisez le code ci-dessous
var array = [[String: AnyObject]]()// Save your data in array
let objectAtZero = array[0] // get first object
let index = (self.array as NSArray).index(of: objectAtZero)
Ou si vous voulez trouver un index sur la base de la clé du dictionnaire. Ici, le tableau contient les objets de la classe Model et la propriété id correspondant.
let userId = 20
if let index = array.index(where: { (dict) -> Bool in
return dict.id == userId // Will found index of matched id
}) {
print("Index found")
}
Toute cette solution fonctionne pour moi
C'est la solution que j'ai pour Swift 4:
let monday = Day(name: "M")
let tuesday = Day(name: "T")
let friday = Day(name: "F")
let days = [monday, tuesday, friday]
let index = days.index(where: {
//important to test with === to be sure it's the same object reference
$0 === tuesday
})
Dans Swift 4, si vous parcourez votre tableau DataModel, assurez-vous que votre modèle de données est conforme à Equatable Protocol, implémentez la méthode lhs = rhs et vous pourrez alors utiliser ".index (of"). Par exemple
class Photo : Equatable{
var imageURL: URL?
init(imageURL: URL){
self.imageURL = imageURL
}
static func == (lhs: Photo, rhs: Photo) -> Bool{
return lhs.imageURL == rhs.imageURL
}
}
Puis,
let index = self.photos.index(of: aPhoto)
Dans Swift 2 (avec Xcode 7), Array
inclut une méthode indexOf
fournie par le protocole CollectionType
. (En fait, deux méthodes indexOf
, l'une qui utilise l'égalité pour faire correspondre un argument et ne autre qui utilise une fermeture.)
Avant Swift 2, il n'existait aucun moyen pour les types génériques tels que les collections de fournir des méthodes pour les types concrets dérivés (tels que les tableaux). Ainsi, dans Swift 1.x, "index of" est une fonction globale ... Et il a également été renommé. Ainsi, dans Swift 1.x, cette fonction globale est appelée find
.
Il est également possible (mais pas nécessaire) d’utiliser la méthode indexOfObject
de NSArray
... ou n’importe laquelle des méthodes de recherche plus sophistiquées de Foundation, qui n’ont pas d’équivalent dans la bibliothèque standard Swift. Juste import Foundation
(ou un autre module qui importe transitoirement Foundation), transformez votre Array
en NSArray
et vous pouvez utiliser les nombreuses méthodes de recherche de NSArray
.
Swift 2.1
var array = ["0","1","2","3"]
if let index = array.indexOf("1") {
array.removeAtIndex(index)
}
print(array) // ["0","2","3"]
Swift
var array = ["0","1","2","3"]
if let index = array.index(of: "1") {
array.remove(at: index)
}
array.remove(at: 1)
Vous pouvez également utiliser la bibliothèque fonctionnelle Dollar pour créer un indexOf sur un tableau en tant que tel http://www.dollarswift.org/#indexof-indexof
$.indexOf([1, 2, 3, 1, 2, 3], value: 2)
=> 1
Si vous travaillez toujours dans Swift 1.x
alors essaye,
let testArray = ["A","B","C"]
let indexOfA = find(testArray, "A")
let indexOfB = find(testArray, "B")
let indexOfC = find(testArray, "C")
Swift 4
Supposons que vous souhaitiez stocker un nombre du tableau appelé cardButtons dans cardNumber, vous pouvez le faire comme suit:
let cardNumber = cardButtons.index(of: sender)
l'expéditeur est le nom de votre bouton
Swift 4
Pour les types de référence:
extension Array where Array.Element: AnyObject {
func index(ofElement element: Element) -> Int? {
for (currentIndex, currentElement) in self.enumerated() {
if currentElement === element {
return currentIndex
}
}
return nil
}
}
Pour Swift 3, vous pouvez utiliser une fonction simple
func find(objecToFind: String?) -> Int? {
for i in 0...arrayName.count {
if arrayName[i] == objectToFind {
return i
}
}
return nil
}
Cela donnera la position du numéro, de sorte que vous pouvez utiliser comme
arrayName.remove(at: (find(objecToFind))!)
J'espère être utile