Question swift for loop: pour index, élément dans tableau?


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

601
2018-06-04 03:19


origine


Réponses:


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

1263
2018-06-04 03:23



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
 */

55
2017-11-30 14:29



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

47
2018-06-12 08:39



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

38
2018-02-09 11:27



Enumerate de base

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

ou avec Swift 3 ...

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

Enumerate, Filter et Map

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

11
2018-01-28 18:03



À partir de Swift 3, il est

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

8
2018-06-20 12:03



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.


7
2017-12-23 14:27



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.


5
2018-05-30 05:48



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

4
2017-10-09 12:06



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.


3
2018-06-12 08:47