web-dev-qa-db-fra.com

Swift pour la boucle: pour l'index, l'élément du tableau?

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):
    ...
717
metaphy

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

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
 */
91
Imanou Petit

À 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)")
}
50
Ricky

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

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.

14
Riajur Rahman

Énumération de base

for (index, element) in arrayOfValues.enumerate() {
// do something useful
}

ou avec Swift 3 ...

for (index, element) in arrayOfValues.enumerated() {
// do something useful
}

Énumérer, filtrer et cartographier

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

Commençant par Swift 3, il s’agit de

for (index, element) in list.enumerated() {
  print("Item \(index): \(element)")
}
8
Jake Lin

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.

7
Cole Campbell

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 .

7
Dara Tith

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
4
Anil Gupta

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

4
Leo Dabus

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 { ... }
3
Vincent

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

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)")
}
0
Ale Mohamad