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
stridePara 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áriousando 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
whereem 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
KeyValuePairsConforme mencionado anteriormente, o
Dicionárionã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
enume 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-incom diferentes exemplos e casos de uso.A postagem
for-inloops em Swift tutorial apareceu primeiro no LogRocket Blog .