Iteração sobre array em Swift: índice e elemento por baixo dos panos

Treinador Online de Python para Iniciantes

Aprenda Python facilmente sem sobrecarga teórica. Resolva tarefas práticas com verificação automática e escreva código diretamente no navegador.

Start Course

Como obter o índice de um elemento ao percorrer um array em Swift? Entendendo uma questão popular

\n\n

Imagine: você está programando em Swift e quer não apenas percorrer um array, mas também saber em que posição cada elemento se encontra. Seja para modificar elementos pelo índice, comparar valores adjacentes ou simplesmente exibir uma lista numerada, a tarefa é a mesma. A pergunta "How to iterate a loop with index and element in Swift" acumulou milhares de visualizações no Stack Overflow. Isso significa que este tópico preocupa muitos.

\n\n

Neste artigo, não vamos apenas dar uma resposta pronta. Vamos olhar por baixo dos panos: analisar quais métodos existem, qual é mais rápido, qual é mais seguro e por que um deles — enumerated() — se tornou o padrão de facto. Vamos lá!

\n\n

O problema: por que o simples for-in não é suficiente?

\n\n

Suponha que você tenha um array de strings:

\n\n
let fruits = ["Maçã", "Banana", "Cereja", "Melão"]
\n\n

A maneira mais óbvia é for-in:

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

Isso exibirá os nomes das frutas. Mas e se você precisar saber o índice? Por exemplo: "1. Maçã, 2. Banana..."? O simples for-in não fornece o índice. Você precisa criar gambiarras:

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

Funciona? Sim. Bonito? Não. E se o array estiver vazio? E se você esquecer de incrementar o index? Bem-vindo ao mundo dos bugs. O Swift oferece soluções mais elegantes.

\n\n

Método nº 1: O clássico — método enumerated()

\n\n

Esta é a maneira mais popular e recomendada. O método enumerated() retorna uma sequência de tuplas (offset: Int, element: Element). Vejamos como funciona:

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

Saída:

\n
1. Maçã\n2. Banana\n3. Cereja\n4. Melão
\n\n

O que acontece por baixo dos panos?

\n\n

enumerated() não cria um novo array. Ele retorna uma sequência preguiçosa do tipo EnumeratedSequence. Isso significa que os elementos não são copiados para uma nova estrutura de dados — eles são "encapsulados" em tempo real. A cada acesso ao próximo elemento, a sequência simplesmente incrementa o contador e retorna uma tupla. Isso é muito eficiente em termos de memória, especialmente para coleções grandes.

\n\n

Uma nuance importante: o offset sempre começa em 0. Se você precisar de um índice começando em 1 (como na numeração de listas), basta adicionar um. O Swift não faz isso por você — é uma decisão consciente dos desenvolvedores da linguagem para manter a consistência com a indexação de arrays.

\n\n

enumerated() com forEach

\n\n

O método forEach também suporta enumerated():

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

A diferença entre for-in e forEach é importante: dentro de forEach não é possível usar break ou continue. Se precisar sair do loop prematuramente — use for-in.

\n\n

Método nº 2: Indexação por intervalo (Range)

\n\n

Uma maneira antiga, mas ainda encontrada, é iterar pelos índices:

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

Parece simples, mas existem armadilhas:

\n\n
    \n
  • Segurança: Se o array mudar durante a iteração (por exemplo, em código multithread), fruits.count pode ficar desatualizado e você pode sair dos limites do array.
  • \n
  • Legibilidade: O código parece mais "de baixo nível". Outros desenvolvedores gastarão um segundo extra para entender o que você está fazendo.
  • \n
  • Desempenho: O acesso por índice fruits[index] é uma operação O(1) para arrays, mas para outras

Blogs

Book Recommendations