Existe-t-il une fonction que je peux utiliser pour parcourir un tableau et avoir à la fois un index et un élément, comme enumerate de python?
for index, element in enumerate(list):
...
Oui. À partir de Swift 3.0, si vous avez besoin de l'index de chaque élément avec sa valeur, vous pouvez utiliser la méthode enumerated()
pour effectuer une itération. sur le tableau. Il retourne 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 s'appelait 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 5 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.enumerated() {
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 envisagez 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)]
Une façon plus rapide de faire ceci est:
let list = [Int](1...5)
let arrayOfTuples = Array(list.enumerated())
print(arrayOfTuples) // prints [(offset: 0, element: 1), (offset: 1, element: 2), (offset: 2, element: 3), (offset: 3, element: 4), (offset: 4, element: 5)]
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 limitations , forEach
peut remplacer avantageusement 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 effectuer une itération manuelle sur votre Array
. Par exemple:
import UIKit
import PlaygroundSupport
class ViewController: UIViewController {
var generator = ["Car", "Bike", "Plane", "Boat"].enumerated().makeIterator()
override func viewDidLoad() {
super.viewDidLoad()
let button = UIButton(type: .system)
button.setTitle("Tap", for: .normal)
button.frame = CGRect(x: 100, y: 100, width: 100, height: 100)
button.addTarget(self, action: #selector(iterate(_:)), for: .touchUpInside)
view.addSubview(button)
}
@objc func iterate(_ sender: UIButton) {
let Tuple = generator.next()
print(String(describing: Tuple))
}
}
PlaygroundPage.current.liveView = ViewController()
/*
Optional((offset: 0, element: "Car"))
Optional((offset: 1, element: "Bike"))
Optional((offset: 2, element: "Plane"))
Optional((offset: 3, element: "Boat"))
nil
nil
nil
*/
À partir de Swift 2, la fonction enumerate doit être appelée sur la collection de la manière suivante:
for (index, element) in list.enumerate() {
print("Item \(index): \(element)")
}
J'ai trouvé cette réponse en cherchant un moyen de faire cela 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)")
}
Vous pouvez simplement utiliser une boucle d’énumération pour obtenir le résultat souhaité:
Swift 2:
for (index, element) in elements.enumerate() {
print("\(index): \(element)")
}
Swift 3 & 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 ça aide.
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 énumérer en combinaison avec map ou filter. Par exemple, en opérant sur plusieurs tableaux.
Dans ce tableau, je voulais filtrer les éléments impairs ou même indexés et les convertir d'Ints en Doubles. Ainsi, enumerate()
vous récupère l'index et l'élément, puis le filtre vérifie l'index, et enfin, pour vous débarrasser du tuple résultant, je le mappe uniquement à 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)
})
Commençant par Swift 3, il s’agit de
for (index, element) in list.enumerated() {
print("Item \(index): \(element)")
}
Utiliser .enumerate()
fonctionne, mais ne fournit pas le véritable index de l'élément; il fournit uniquement un Int commençant par 0 et incrémenté de 1 pour chaque élément successif. Cela n’est généralement pas pertinent, mais il existe un risque de comportement inattendu lorsqu’il est utilisé avec le type ArraySlice
. 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 quelque peu artificiel, et ce n'est pas un problème courant dans la pratique, mais je pense néanmoins que cela vaut la peine de savoir que cela peut arriver.
C'est la formule de 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 .
Xcode 8 et Swift 3: Le tableau peut être énuméré à l'aide de tempArray.enumerated()
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
Pour être complet, vous pouvez simplement parcourir vos index de tableau et utiliser indice pour accéder à l'élément à l'index correspondant:
let list = [100,200,300,400,500]
for index in list.indices {
print("Element at:", index, " Value:", list[index])
}
Utiliser pour chaque
list.indices.forEach {
print("Element at:", $0, " Value:", list[$0])
}
Utilisation de la méthode collection enumerated()
. Notez qu'il retourne une collection de tuples avec le offset
et le element
:
for item in list.enumerated() {
print("Element at:", item.offset, " Value:", item.element)
}
en utilisant forEach:
list.enumerated().forEach {
print("Element at:", $0.offset, " Value:", $0.element)
}
Ceux vont imprimer
Elément à: 0 Valeur: 100
Elément à: 1 Valeur: 200
Elément à: 2 Valeur: 300
Elément à: 3 Valeur: 400
Elément à: 4 Valeur: 500
Si vous avez besoin de l'index de tableau (pas l'offset) et de son élément, vous pouvez étendre Collection et créer votre propre méthode pour énumérer ses index:
extension Collection {
func enumeratedIndices(body: ((index: Index, element: Element)) throws -> ()) rethrows {
var index = startIndex
for element in self {
try body((index,element))
formIndex(after: &index)
}
}
}
Essai:
let list = ["100","200","300","400","500"]
list.dropFirst(2).enumeratedIndices {
print("Index:", $0.index, "Element:", $0.element)
}
Cela va p [rint
Indice: 2 Élément: 300
Indice: 3 Élément: 400
Indice: 4 Elément: 500
Pour ceux qui veulent utiliser forEach
.
Swift 4
extension Array {
func forEachWithIndex(_ body: (Int, Element) throws -> Void) rethrows {
try Zip((startIndex ..< endIndex), self).forEach(body)
}
}
Ou
array.enumerated().forEach { ... }
Personnellement, je préfère utiliser la méthode forEach
:
list.enumerated().forEach { (index, element) in
...
}
Vous pouvez également utiliser la version courte:
list.enumerated().forEach { print("index: \($0.0), value: \($0.1)") }
Pour ce que vous voulez faire, vous devriez utiliser la méthode enumerated()
sur votre Array:
for (index, element) in list.enumerated() {
print("\(index) - \(element)")
}