Em termos gerais, quando algo é executado em um loop, ele repete as mesmas coisas continuamente. Por exemplo, um loop seria iterar o número de postagens do blog e exibi-las na página principal.

Existem diferentes tipos de loops para o fluxo de controle no Swift. São os loops for-in , forEach , while e repeat-while . Neste artigo, apresentaremos uma visão geral básica dos loops for-in em Swift. Em seguida, demonstraremos como trabalhar com eles usando exemplos e casos de uso com diferentes tipos de dados.

Vamos nos concentrar no seguinte:

  • A sintaxe dos loops for-in
  • Matrizes
  • Alcance e passada
  • dicionários
  • Enums

Para acompanhar, você deve ter conhecimento básico da linguagem Swift.

A sintaxe dos loops for-in

A sintaxe começa com a palavra para , seguida pelo elemento específico em um loop que é criado como uma constante. Seguimos pela palavra em e, finalmente, a sequência que você deseja repetir:

 para elemento em elementos { //faça algo com o elemento
}

Por exemplo, temos uma lista de ações, cada uma incluindo seu preço, em uma data específica:

 struct Stock { var name: String preço var: duplo var data=Data ()
}

Queremos fazer um loop sobre a matriz e imprimir os dados de cada ação. A sintaxe do loop será semelhante a esta:

//MARCA:-EXEMPLO
func printDetails (para ações: [Estoque]) { para estoque em estoque { imprimir (stock.name) imprimir (estoque.preço) imprimir (stock.date) }
} //MARCA:-USO
deixe ações=[estoque (nome:"Banana", preço: 125), Estoque (nome:"TapeBook", preço: 320), Estoque (nome:"Ramalon", preço: 3.200)] printDetails (para: ações) //MARCA:-SAÍDA
Banana
125,0
2021-05-21 22:40:42 +0000
TapeBook
320,0
2021-05-21 22:40:42 +0000
Ramalon
3200,0
2021-05-21 22:40:42 +0000

Com conhecimento da sintaxe básica, vamos prosseguir para o loop da estrutura de dados fundamental: Array !

Matrizes

Da documentação oficial do Swift , “Uma matriz armazena valores do mesmo tipo em uma lista ordenada. O mesmo valor pode aparecer em uma matriz várias vezes em posições diferentes. ”

Usamos loops for-in para iterar sobre os valores armazenados e, em seguida, acessar cada valor na matriz.

Exemplo básico

Suponha um aplicativo em que estamos rastreando a corrida de um usuário. Em cada local, queremos rastrear sua velocidade. Assim, no aplicativo, recebemos uma variedade de locais:

 permitir localizações: [CLLocation]=[]

Fazemos um loop pela matriz e, para cada local, imprimimos a velocidade naquele local específico:

 para localização em locais { print ("A velocidade no local (\ (location.coordinate.latitude), \ (location.coordinate.longitude) é \ (location.speed)")
}

Fazendo outra ilustração, criamos uma matriz bidimensional 10 × 10 e imprimimos o valor em cada ponto:

 var board: [[Int]]=Array (repetindo: Array (repetindo: 0, contagem: 10), contagem: 10) para linha no tabuleiro { para o número na linha { //imprime 0, cem vezes imprimir (número) }
}

Usando a cláusula where

Existem casos em que queremos restringir a sequência apenas aos elementos que correspondem a uma condição particular. Neste cenário, usamos a palavra-chave where .

Em um aplicativo de tarefas, precisamos do subconjunto de metas concluídas de todas as metas. Suponha um modelo como este:

 struct Objetivo: Identificável, Hashable { var id=UUID () var name: String="Nome da meta" var data=Data () var goalCompleted: Bool=false
}

E nosso aplicativo tem uma matriz para Goal . Queremos fazer um loop pela matriz e acessar apenas as metas que foram concluídas:

//MARCA:-EXEMPLO
func getCompletedGoals (para metas: [Goal]) { para meta em metas em que goal.goalCompleted==true { ///Acesso apenas a metas concluídas. imprimir (objetivo) }
} //MARCA:-USO
let goals=[Goal (name:"Aprender a sintaxe básica de loops for-in", goalCompleted: true), Objetivo (nome:"Ler sobre loops e dicionários for-in"), Objetivo (nome:"Ler sobre loops for-in e enums")] getCompletedGoals (para: metas) //MARCA:-SAÍDA
Objetivo (id: B7B148D6-853B-486A-8407-CD03A904B348, nome:"Aprenda a sintaxe básica de loops for-in", data: 2021-05-21 22:50:38 +0000, goalCompleted: true)

Usando enumerated()

Para acessar cada índice do elemento simultaneamente, podemos usar o método de instância enumerated () . Ele retorna uma sequência de pares que contém o índice e também o valor do elemento. Tomando o exemplo anterior, se quisermos listar o índice da localização na matriz, podemos escrever isto:

 para (índice, localização) em locations.enumerated () { print ("A velocidade no local (\ (location.coordinate.latitude), \ (location.coordinate.longitude) é \ (location.speed)") print ("O índice para este local é \ (índice)")
}

Usando indices

Se quisermos apenas o índice do elemento na matriz, podemos usar índices . Isso representa os índices válidos em uma matriz em ordem crescente. Ele faz um loop de 0 ao último elemento na matriz, ou seja, array.count :

 para índice em array.indices { //Acesse o índice
}

Usando a matriz bidimensional que criamos anteriormente, iteramos cada ponto e atribuímos a ele um valor inteiro aleatório:

//MARCA:-EXEMPLO
func updateValues ​​(of board: inout [[Int]]) { para rowIndex em board.indices { para columnIndex no quadro [0].indices { tabuleiro \ [rowIndex \] [columnIndex]=Int.random (em: 0.. <10) } imprimir (placa [rowIndex]) }
} //MARCA:-USO
var board: [[Int]]=Array (repetindo: Array (repetindo: 0, contagem: 10), contagem: 10) updateValues ​​(de: & placa) //MARCA:-SAÍDA
[9, 4, 1, 7, 5, 2, 6, 4, 7, 4]
[1, 0, 1, 0, 5, 4, 5, 6, 7, 9]
[4, 7, 6, 3, 8, 9, 3, 5, 9, 5]
[8, 0, 9, 9, 6, 1, 2, 0, 2, 7]
[3, 7, 4, 1, 3, 4, 9, 9, 5, 6]
[5, 2, 5, 1, 8, 1, 8, 0, 0, 1]
[0, 4, 3, 4, 0, 6, 1, 8, 7, 5]
[7, 7, 7, 9, 1, 3, 6, 4, 0, 1]
[9, 5, 6, 5, 3, 8, 0, 1, 3, 4]
[1, 7, 7, 3, 1, 0, 7, 4, 5, 6]

Usando um padrão opcional

Em um caso em que a sequência contém valores opcionais, podemos filtrar os valores nulos usando para case let , executando o loop apenas para elementos não nulos.

Com base no exemplo anterior do aplicativo de tarefas, vamos supor que alguns de nossos objetivos não tenham valor. O getCompletedGoals (for goals:) agora aceita uma matriz de Goal opcional:

//MARCA:-EXEMPLO
func getCompletedGoals (para metas: [Goal?]) { para o caso, deixe o objetivo? em metas em que goal.goalCompleted==false { ///Acesso apenas a metas concluídas. imprimir (objetivo) }
} //MARCA:-USO
deixe metas: [Goal?]=[Goal (name:"Aprenda algo novo!", goalCompleted: true), Objetivo (nome:"Ler sobre loops e dicionários for-in"), nada, Objetivo (nome:"Ler sobre loops for-in e enums"), nada] getCompletedGoals (para: metas) //MARCA:-SAÍDA
Objetivo (id: F6CB6D77-9047-4155-99F9-24F6D178AC2B, nome:"Ler sobre loops e dicionários for-in", data: 2021-05-21 23:04:58 +0000, goalCompleted: false)
Objetivo (id: 822CB7C6-301C-47CE-AFEE-4B17A10EE5DC, nome:"Ler sobre loops e enums for-in", data: 2021-05-21 23:04:58 +0000, objetivo Concluído: falso)

Alcance e passada

Também podemos usar loops for-in para percorrer intervalos numéricos codificados. Eles podem ser divididos em duas partes:

  • Usando um operador de intervalo fechado ()
  • Usando um operador de intervalo semi-aberto (.. <)

Usando um operador de intervalo fechado

Um operador de intervalo fechado cria um intervalo incluindo ambos os elementos finais. Um exemplo básico de como trabalhar com esse operador é imprimir 10 números. Aqui, 1 e 10 também serão impressos:

 para número em 1... 10 { print ("O número é \ (número)")
}

FizzBuzz é um exercício de programação simples onde podemos usar para loops for-in . O prompt segue estas linhas:

Escreva um programa que imprima números de 1 a n. Múltiplos de 3 imprimem “Fizz” em vez do número e múltiplos de 5 imprimem “Buzz”. Para números que são múltiplos de 3 e 5, imprima “FizzBuzz” em vez do número.

Fazemos um loop pelos números de 1 a n usando o operador de intervalo fechado para criar uma constante ClosedRange . Em seguida, percorremos novamente a tupla no mapeamento e verificamos cada elemento na tupla. Se o número for um múltiplo de 3, acrescentamos Fizz à string .

À medida que verificamos cada elemento no mapeamento , se também for um múltiplo de 5, acrescentamos Buzz à string com o resultado sendo FizzBuzz :

//MARCA:-EXEMPLO
func fizzBuzz (para lastNumber: Int) { var result=[String] () deixe mapeamento=[(número: 3, valor:"Fizz"), (número: 5, valor:"Buzz")] para o número em 1... lastNumber { var string="" para tupla no mapeamento { se o número% tuple.number==0 { string +=tuple.value } } if string==""{ string +="\ (número)" } imprimir (resultado) } resultado de retorno
} //MARCA:-USO
fizzBuzz (para: 10) //MARCA:-SAÍDA
["1","2","Fizz","4","Buzz","Fizz","7","8","Fizz","Buzz"]

Usando um operador de alcance semiaberto

Um operador de intervalo semi-aberto cria um intervalo excluindo o último elemento. Um exemplo básico de trabalho com este operador é acessar os índices de uma matriz:

 para índice em 0.. 

Usando stride

Para casos em que você deseja pular elementos em um loop por um número específico, você pode usar stride . Também podemos usar isso para voltar em um loop, começando do último elemento e indo para o primeiro.

Voltando ao exemplo em que criamos uma matriz bidimensional de tamanho 10 × 10 com valores aleatórios, queremos imprimir cada elemento alternativo na primeira linha:

//MARCA:-EXEMPLO
func printFirstRow (para placa: [[Int]]) { para rowIndex in stride (de: board.count-1, a: 0, por:-2) { imprimir (placa \ [rowIndex \] [0]) }
} //MARCA:-USO
printFirstRow (para: placa) //MARCA:-SAÍDA
7
4
4
4
8

Agora, queremos imprimir todos os elementos alternativos na primeira coluna, mas na ordem inversa:

//MARCA:-EXEMPLO
func printFirstColumn (para placa: [[Int]]) { para rowIndex in stride (de: board.count-1, a: 0, por:-2) { imprimir (placa \ [rowIndex \] [0]) }
} //MARCA:-USO
printFirstColumn (para: placa) //MARCA:-SAÍDA
8
6
0
6
5

Dicionários

Também podemos iterar por meio de um Dicionário usando loops for-in , embora o resultado seja desordenado. A sintaxe é semelhante a matrizes, com cada elemento tendo sua chave e seu valor:

//MARCA:-EXEMPLO
func printDictionary (para números: [Int: Int]) { para número em números { //número é um Dicionário .Element print ("O valor da chave \ (number.key) é \ (number.value)") }
} //MARCA:-USO
deixe os números: [Int: Int]=[1: 2, 2: 3, 3: 4] printDictionary (para: números) //MARCA:-SAÍDA
O valor da chave 1 é 2
O valor da chave 2 é 3
O valor da chave 3 é 4

Também podemos usar explicitamente nossas próprias palavras-chave:

//MARCA:-EXEMPLO
func printStockPrices (para ações: [String: Int]) { para (nome, preço) em ações { print ("\ (nome) está atualmente avaliado em $ \ (preço).") }
} //MARCA:-USO
deixe ações: [String: Int]=["Banana": 125,"TapeBook": 320,"Ramalon": 3200] printStockPrices (para: ações) //MARCA:-SAÍDA
A banana está atualmente avaliada em $ 125.
Ramalon está atualmente avaliado em $ 3.200.
O TapeBook está atualmente avaliado em $ 320.

Podemos usar where em dicionários também:

//MARCA:-EXEMPLO
func printStockPrices (para ações: [String: Int]) { para (nome, preço) em ações onde nome=="Banana"{ print ("\ (nome) está atualmente avaliado em $ \ (preço).") }
} //MARCA:-USO
deixe ações: [String: Int]=["Banana": 125,"TapeBook": 320,"Ramalon": 3200] printStockPrices (para: ações) //MARCA:-SAÍDA
A banana está atualmente avaliada em $ 125.

Se quiser o preço mais alto neste dicionário, você pode classificar o dicionário usando classificado (por:) :

//MARCA:-EXEMPLO
func printStockPrices (para ações: [String: Int]) { para (nome, preço) em ações. ordenado (por: {$ 0.valor> $ 1.valor}) { print ("\ (nome) está atualmente avaliado em $ \ (preço).") }
} //MARCA:-USO
deixe ações: [String: Int]=["Banana": 125,"TapeBook": 320,"Ramalon": 3200] printStockPrices (para: ações) //MARCA:-SAÍDA
Ramalon está avaliado atualmente em $ 3.200.
O TapeBook está atualmente avaliado em $ 320.
A banana está atualmente avaliada em $ 125.

Usando KeyValuePairs

Conforme mencionado anteriormente, o Dicionário não possui uma ordem definida. Se quiser pares de valores-chave ordenados, você pode usar KeyValuePairs . Isso é útil nos casos em que você está disposto a sacrificar o tempo de pesquisa rápido e constante pelo tempo linear:

//MARCA:-EXEMPLO
func printStockPrices (para ações: KeyValuePairs ) { para (nome, preço) em ações { print ("\ (nome) está atualmente avaliado em $ \ (preço).") }
} //MARCA:-USO
deixe ações: KeyValuePairs=["Banana": 125,"TapeBook": 320,"Ramalon": 3200] printStockPrices (para: ações) //MARCA:-SAÍDA
A banana está atualmente avaliada em $ 125.
O TapeBook está atualmente avaliado em $ 320.
Ramalon está avaliado atualmente em $ 3.200.

Enums

Você pode até mesmo iterar em um enum no Swift , obedecendo a um protocolo denominado CaseIterable . Este tipo fornece uma coleção de todos os seus valores. Em nosso caso, ele fornece todos os casos em Enum . Para acessá-los, usamos a propriedade allCases .

Com outro exemplo, estamos trabalhando em um jogo hiper casual. Precisamos definir diferentes modos de jogo na tela principal. Vamos criar um enum e iterar sobre ele para acessar o nome do modo e o nome da imagem:

 enum GameModes: String { fliperama desafio de caso caso casual caso cronometrado
} extensão GameModes { var name: String { self.rawValue.capitalized } var image: String { switch self { case.arcade: return"& # x1f579;" case.casual: return"& # x1f3ae;" case.challenge: return"& # x1f396;" case.timed: return"⏳" } }
} extensão GameModes: CaseIterable {} //Uso
para o modo em GameModes.allCases { let gameOptionsView=GameOptionsView () gameOptionsStackView.addArrangedSubview (gameOptionsView) gameOptionsView.set (nome: mode.name, image: mode.image)
}

Conclusão

Os loops são conhecimentos fundamentais que ajudam você a se tornar melhor no Swift. Neste artigo, cobrimos uma visão geral dos loops for-in com diferentes exemplos e casos de uso.

A postagem for-in loops em Swift tutorial apareceu primeiro no LogRocket Blog .