Y at-il une fonction que je peux utiliser pour itérer sur un tableau et avoir à la fois l'index et l'élément, comme l'énumération de python?
for index, element in enumerate(list):
...
Y at-il une fonction que je peux utiliser pour itérer sur un tableau et avoir à la fois l'index et l'élément, comme l'énumération de python?
for index, element in enumerate(list):
...
Oui. À partir de Swift 3.0, si vous avez besoin de l'index pour chaque élément avec sa valeur, vous pouvez utiliser le enumerated()
méthode itérer sur le tableau. Il renvoie une séquence de paires composée de l'index et de la valeur de chaque élément du tableau. Par exemple:
for (index, element) in list.enumerated() {
print("Item \(index): \(element)")
}
Avant Swift 3.0 et après Swift 2.0, la fonction était appelée enumerate()
:
for (index, element) in list.enumerate() {
print("Item \(index): \(element)")
}
Avant Swift 2.0, enumerate
était une fonction globale.
for (index, element) in enumerate(list) {
println("Item \(index): \(element)")
}
Swift 3 fournit une méthode appelée enumerated()
pour Array
. enumerated()
a la déclaration suivante:
func enumerated() -> EnumeratedSequence<Array<Element>>
Renvoie une séquence de paires (n, x), où n représente un entier consécutif commençant à zéro et x représente un élément de la séquence.
Dans les cas les plus simples, vous pouvez utiliser enumerated()
avec une boucle for. Par exemple:
let list = ["Car", "Bike", "Plane", "Boat"]
for (index, element) in list.enumerate() {
print(index, ":", element)
}
/*
prints:
0 : Car
1 : Bike
2 : Plane
3 : Boat
*/
Notez cependant que vous n'êtes pas limité à utiliser enumerated()
avec une boucle for. En fait, si vous prévoyez d'utiliser enumerated()
avec une boucle for pour quelque chose de similaire au code suivant, vous le faites mal:
let list = [Int](1...5)
var arrayOfTuples = [(Int, Int)]()
for (index, element) in list.enumerated() {
arrayOfTuples += [(index, element)]
}
print(arrayOfTuples) // prints [(0, 1), (1, 2), (2, 3), (3, 4), (4, 5)]
La bonne façon de le faire est la suivante:
let list = [Int](1...5)
let arrayOfTuples = Array(list.enumerated())
print(arrayOfTuples) // prints [(0, 1), (1, 2), (2, 3), (3, 4), (4, 5)]
Comme alternative, vous pouvez également utiliser enumerated()
avec map
:
let list = [Int](1...5)
let arrayOfDictionaries = list.enumerated().map { (a, b) in return [a : b] }
print(arrayOfDictionaries) // prints [[0: 1], [1: 2], [2: 3], [3: 4], [4: 5]]
De plus, bien qu'il ait quelques limites, forEach
peut être un bon remplacement à une boucle for:
let list = [Int](1...5)
list.reversed().enumerated().forEach { print($0, ":", $1) }
/*
prints:
0 : 5
1 : 4
2 : 3
3 : 2
4 : 1
*/
En utilisant enumerated()
et makeIterator()
, vous pouvez même itérer manuellement sur votre Array
. Par exemple:
import UIKit
class ViewController: UIViewController {
var generator = ["Car", "Bike", "Plane", "Boat"].enumerated().makeIterator()
// Link this IBAction to a UIButton in your storyboard
@IBAction func iterate(_ sender: UIButton) {
let tuple: (offset: Int, element: String)? = generator.next()
print(String(describing: tuple))
}
}
/*
Will print the following lines for 6 `touch up inside`:
Optional((0, "Car"))
Optional((1, "Bike"))
Optional((2, "Plane"))
Optional((3, "Boat"))
nil
nil
*/
À partir de Swift 2, la fonction enumerate doit être appelée sur la collection comme suit:
for (index, element) in list.enumerate() {
print("Item \(index): \(element)")
}
J'ai trouvé cette réponse en cherchant un moyen de le faire avec un dictionnaire, et il s'avère qu'il est assez facile de l'adapter, il suffit de passer un tuple pour l'élément.
// Swift 2
var list = ["a": 1, "b": 2]
for (index, (letter, value)) in list.enumerate() {
print("Item \(index): \(letter) \(value)")
}
for (index, element) in arrayOfValues.enumerate() {
// do something useful
}
ou avec Swift 3 ...
for (index, element) in arrayOfValues.enumerated() {
// do something useful
}
Cependant, j'utilise le plus souvent l'énumération en combinaison avec une carte ou un filtre. Par exemple avec opérer sur un couple de tableaux.
Dans ce tableau, je voulais filtrer les éléments indexés pairs ou impairs et les convertir d'Ints en Doubles. Alors enumerate()
obtient l'index et l'élément, puis le filtre vérifie l'index, et enfin pour se débarrasser du tuple résultant je le mappe juste à l'élément.
let evens = arrayOfValues.enumerate().filter({
(index: Int, element: Int) -> Bool in
return index % 2 == 0
}).map({ (_: Int, element: Int) -> Double in
return Double(element)
})
let odds = arrayOfValues.enumerate().filter({
(index: Int, element: Int) -> Bool in
return index % 2 != 0
}).map({ (_: Int, element: Int) -> Double in
return Double(element)
})
À partir de Swift 3, il est
for (index, element) in list.enumerated() {
print("Item \(index): \(element)")
}
C'est la formule de la boucle d'énumération:
for (index, value) in shoppingList.enumerate() {
print("Item \(index + 1): \(value)")
}
pour plus de détails, vous pouvez vérifier Ici.
En utilisant .enumerate()
fonctionne, mais il ne fournit pas le véritable index de l'élément; il fournit seulement un Int commençant par 0 et incrémentant de 1 pour chaque élément successif. Ce n'est généralement pas pertinent, mais il existe un risque de comportement inattendu lorsqu'il est utilisé avec ArraySlice
type. Prenez le code suivant:
let a = ["a", "b", "c", "d", "e"]
a.indices //=> 0..<5
let aSlice = a[1..<4] //=> ArraySlice with ["b", "c", "d"]
aSlice.indices //=> 1..<4
var test = [Int: String]()
for (index, element) in aSlice.enumerate() {
test[index] = element
}
test //=> [0: "b", 1: "c", 2: "d"] // indices presented as 0..<3, but they are actually 1..<4
test[0] == aSlice[0] // ERROR: out of bounds
C'est un exemple un peu artificiel, et ce n'est pas un problème commun dans la pratique, mais je pense qu'il vaut la peine de savoir que cela peut arriver.
Xcode 8 et Swift 3: Tableau peut être énuméré en utilisant tempArray.enumerate ()
Exemple:
var someStrs = [String]()
someStrs.append("Apple")
someStrs.append("Amazon")
someStrs += ["Google"]
for (index, item) in someStrs.enumerated()
{
print("Value at index = \(index) is \(item)").
}
console:
Value at index = 0 is Apple
Value at index = 1 is Amazon
Value at index = 2 is Google
Vous pouvez simplement utiliser la boucle d'énumération pour obtenir le résultat désiré:
Swift 2:
for (index, element) in elements.enumerate() {
print("\(index): \(element)")
}
Swift 3 et 4:
for (index, element) in elements.enumerated() {
print("\(index): \(element)")
}
Ou vous pouvez simplement passer par une boucle for pour obtenir le même résultat:
for index in 0..<elements.count {
let element = elements[index]
print("\(index): \(element)")
}
J'espère que cela aide.