Iteración sobre arreglos en Swift: índice y elemento bajo el capó

Entrenador de Python en Línea para Principiantes

Aprende Python fácilmente sin sobrecargarte de teoría. Resuelve tareas prácticas con verificación automática, recibe pistas y escribe código directamente en el navegador, sin instalar nada.

Start Course

¿Cómo obtener el índice de un elemento al recorrer un arreglo en Swift? Analizando una pregunta popular

\n\n

Imagine: está escribiendo en Swift y no solo quiere recorrer un arreglo, sino también saber en qué posición se encuentra cada elemento. Ya sea que necesite modificar elementos por índice, comparar valores adyacentes o simplemente mostrar una lista numerada, la tarea es la misma. La pregunta "How to iterate a loop with index and element in Swift" ha acumulado miles de visitas en Stack Overflow. Esto significa que este tema preocupa a muchos.

\n\n

En este artículo no solo daremos una respuesta preparada. Miraremos bajo el capó: analizaremos qué métodos existen, cuál es más rápido, cuál es más seguro y por qué uno de ellos — enumerated() — se ha convertido en el estándar de facto. ¡Allá vamos!

\n\n

El problema: ¿por qué el simple for-in no es suficiente?

\n\n

Supongamos que tiene un arreglo de cadenas:

\n\n
let fruits = ["Manzana", "Banana", "Cereza", "Melón"]
\n\n

La forma más obvia es for-in:

\n\n
for fruit in fruits {\n    print(fruit)\n}
\n\n

Esto imprimirá los nombres de las frutas. Pero, ¿qué pasa si necesita saber el índice? Por ejemplo: "1. Manzana, 2. Banana..."? El simple for-in no proporciona el índice. Hay que inventar soluciones improvisadas:

\n\n
var index = 0\nfor fruit in fruits {\n    print("\\(index). \\(fruit)")\n    index += 1\n}
\n\n

¿Funciona? Sí. ¿Es bonito? No. ¿Y si el arreglo está vacío? ¿Y si accidentalmente olvida incrementar index? Bienvenido al mundo de los errores. Swift ofrece soluciones más elegantes.

\n\n

Método n.º 1: El clásico — método enumerated()

\n\n

Esta es la forma más popular y recomendada. El método enumerated() devuelve una secuencia de tuplas (offset: Int, element: Element). Veamos cómo funciona:

\n\n
for (index, fruit) in fruits.enumerated() {\n    print("\\(index + 1). \\(fruit)")\n}
\n\n

Salida:

\n
1. Manzana\n2. Banana\n3. Cereza\n4. Melón
\n\n

¿Qué sucede bajo el capó?

\n\n

enumerated() no crea un nuevo arreglo. Devuelve una secuencia perezosa de tipo EnumeratedSequence. Esto significa que los elementos no se copian a una nueva estructura de datos, sino que se "envuelven" sobre la marcha. Cada vez que se accede al siguiente elemento, la secuencia simplemente incrementa el contador y devuelve una tupla. Esto es muy eficiente en términos de memoria, especialmente para colecciones grandes.

\n\n

Un matiz importante: offset siempre comienza en 0. Si necesita un índice comenzando en 1 (como en la numeración de listas), simplemente sume uno. Swift no lo hace por usted; esta es una decisión consciente de los desarrolladores del lenguaje para mantener la uniformidad con la indexación de arreglos.

\n\n

enumerated() con forEach

\n\n

El método forEach también admite enumerated():

\n\n
fruits.enumerated().forEach { (index, fruit) in\n    print("\\(index). \\(fruit)")\n}
\n\n

La diferencia entre for-in y forEach es importante: dentro de forEach no se puede usar break o continue. Si necesita salir del bucle antes de tiempo, use for-in.

\n\n

Método n.º 2: Indexación mediante rango (Range)

\n\n

Una forma antigua, pero que aún se encuentra, es iterar sobre los índices:

\n\n
for index in 0..<fruits.count {\n    print("\\(index). \\(fruits[index])")\n}
\n\n

Parece sencillo. Pero hay trampas:

\n\n
    \n
  • Seguridad: Si el arreglo cambia durante la iteración (por ejemplo, en código multiproceso), fruits.count puede quedar desactualizado y se saldrá de los límites del arreglo.
  • \n
  • Legibilidad: El código parece más de "bajo nivel". Otros desarrolladores perderán un segundo extra para entender lo que está haciendo.
  • \n
  • Rendimiento: El acceso por índice fruits[index] es una operación O(1) para arreglos, pero para otros

Blogs

Book Recommendations