with loop index for arrays swift

arrays - with - swift for loop: para index, element in array?



swift 4 for loop (12)

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

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


Enumeración básica

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 mapear

Sin embargo, la mayoría de las veces utilizo enumerar en combinación con mapa o filtro. Por ejemplo, con la operación en un par de matrices.

En esta matriz, quería filtrar elementos impares o incluso indexados y convertirlos de Ints a Dobles. Así que enumerate() obtiene su índice y el elemento, luego el filtro verifica el índice y, finalmente, para deshacerse de la tupla resultante, la 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) })


A partir de Swift 3, es

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


Comenzando con Swift 2, la función de enumeración debe llamarse en la colección de esta manera:

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


El uso de .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 el tipo ArraySlice . 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 un tanto artificial, y no es un problema común en la práctica, pero creo que vale la pena saber que esto puede suceder.


Encontré esta respuesta mientras buscaba la forma de hacerlo con un Diccionario , y resulta que es bastante fácil adaptarlo, solo 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)") }


Esta es la fórmula del bucle de enumeración:

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

Para más detalles puedes consultar Here .


Para aquellos que quieren usar forEach .

Swift 4

extension Array { func forEachWithIndex(_ body: (Int, Element) throws -> Void) rethrows { try zip((startIndex ..< endIndex), self).forEach(body) } }

O

array.enumerated().forEach { ... }


Personalmente prefiero usar el método forEach :

list.enumerated().forEach { (index, element) in ... }

También puede utilizar la versión corta:

list.enumerated().forEach { print("index: /($0.0), value: /($0.1)") }


Sí. A partir de Swift 3.0, si necesita el índice para cada elemento junto con su valor, puede usar el método enumerated() para iterar sobre la matriz. Devuelve una secuencia de pares compuesta por el índice y el valor de cada elemento de 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, la función se llamaba enumerate() :

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

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

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


Simplemente puede usar el bucle de enumeración para obtener el resultado deseado:

Swift 2:

for (index, element) in elements.enumerate() { print("/(index): /(element)") }

Swift 3 y 4:

for (index, element) in elements.enumerated() { print("/(index): /(element)") }

O simplemente puede ir a través de un bucle for para obtener el mismo resultado:

for index in 0..<elements.count { let element = elements[index] print("/(index): /(element)") }

Espero eso ayude.


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 número 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 planeas 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 algunas limitations , 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 */

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


Xcode 8 y Swift 3: Array se pueden 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