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 8Agora, 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 5Dicionários
Também podemos iterar por meio de um
Dicionário
usando loopsfor-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 usarKeyValuePairs
. 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 emEnum
. Para acessá-los, usamos a propriedadeallCases
.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 .