Pregunta swift for loop: para index, element in array?


¿Hay alguna función que pueda usar para iterar sobre una matriz y tener tanto un índice como un elemento, como la enumeración de python?

for index, element in enumerate(list):
    ...

601
2018-06-04 03:19


origen


Respuestas:


Sí. A partir de Swift 3.0, si necesita el índice para cada elemento junto con su valor, puede usar enumerated() método para iterar sobre la matriz. Devuelve una secuencia de pares compuesta por el índice y el valor de cada elemento en la matriz. Por ejemplo:

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

Antes de Swift 3.0 y después de Swift 2.0, se llamaba a la función enumerate():

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

Antes de Swift 2.0, enumerate fue una función global.

for (index, element) in enumerate(list) {
    println("Item \(index): \(element)")
}

1263
2018-06-04 03:23



Swift 3 proporciona un método llamado enumerated() para Array. enumerated() tiene la siguiente declaración:

func enumerated() -> EnumeratedSequence<Array<Element>>

Devuelve una secuencia de pares (n, x), donde n representa un entero consecutivo que comienza en cero, y x representa un elemento de la secuencia.


En los casos más simples, puede usar enumerated() con un bucle for. Por ejemplo:

let list = ["Car", "Bike", "Plane", "Boat"]
for (index, element) in list.enumerate() {
    print(index, ":", element)
}

/*
prints:
0 : Car
1 : Bike
2 : Plane
3 : Boat
*/

Sin embargo, tenga en cuenta que no está limitado a usar enumerated() con un bucle for. De hecho, si planea usar enumerated() con un bucle for para algo similar al siguiente código, lo estás haciendo 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 forma correcta de hacer esto es:

let list = [Int](1...5)
let arrayOfTuples = Array(list.enumerated())
print(arrayOfTuples) // prints [(0, 1), (1, 2), (2, 3), (3, 4), (4, 5)]

Como alternativa, también puede usar enumerated() con 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]]

Además, aunque tiene algunos limitaciones, forEach puede ser un buen reemplazo para un bucle for:

let list = [Int](1...5)
list.reversed().enumerated().forEach { print($0, ":", $1) }

/*
prints:
0 : 5
1 : 4
2 : 3
3 : 2
4 : 1
*/

Mediante el uso enumerated() y makeIterator(), puede incluso iterar manualmente en su Array. Por ejemplo:

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



Comenzando con Swift 2, la función enumerate necesita ser llamada en la colección de la siguiente manera:

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

47
2018-06-12 08:39



Encontré esta respuesta mientras buscaba una manera de hacerlo con un Diccionario, y resulta que es bastante fácil adaptarlo, simplemente pase una tupla para el elemento.

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



Enumerar básico

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

o con Swift 3 ...

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

Enumerar, filtrar y mapa

Sin embargo, con mayor frecuencia uso enumerate en combinación con un mapa o filtro. Por ejemplo, al operar en un par de arreglos.

En esta matriz, quería filtrar elementos impares o incluso indexados y convertirlos de Ints a Dobles. Asi que enumerate() obtiene su índice y el elemento, luego filtra el índice y finalmente, para deshacerse de la tupla resultante, lo mapeo solo al elemento.

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



Comenzando con Swift 3, es

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

8
2018-06-20 12:03



Esta es la Fórmula del ciclo de Enumeración:

for (index, value) in shoppingList.enumerate() {
print("Item \(index + 1): \(value)")
}

para más detalles puedes consultar aquí.


7
2017-12-23 14:27



Utilizando .enumerate() funciona, pero no proporciona el índice verdadero del elemento; solo proporciona un Int que comienza con 0 e incrementa en 1 para cada elemento sucesivo. Esto generalmente es irrelevante, pero existe la posibilidad de un comportamiento inesperado cuando se usa con ArraySlice tipo. Toma el siguiente código:

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

Es un ejemplo algo artificial, y no es un problema común en la práctica, pero aún así creo que vale la pena saber que esto puede suceder.


5
2018-05-30 05:48



Xcode 8 y Swift 3: La matriz se puede enumerar usando tempArray.enumerate ()

Ejemplo:

var someStrs = [String]()

someStrs.append("Apple")  
someStrs.append("Amazon")  
someStrs += ["Google"]    


for (index, item) in someStrs.enumerated()  
{  
        print("Value at index = \(index) is \(item)").  
}

consola:

Value at index = 0 is Apple
Value at index = 1 is Amazon
Value at index = 2 is Google

4
2017-10-09 12:06