Higher-Order Personalizadas
Parte da seção Lógica e Fluxo do Journey de Swift da Coddy — lição 42 de 56.
Agora você pode escrever suas próprias funções de ordem superior e elas se encaixarão perfeitamente ao lado de map e filter. O formato é sempre o mesmo: receber um parâmetro de closure, chamá-lo dentro do loop e retornar o resultado.
extension Array {
func myMap<T>(_ transform: (Element) -> T) -> [T] {
var result: [T] = []
for item in self {
result.append(transform(item))
}
return result
}
}
[1, 2, 3].myMap { $0 * 10 } // [10, 20, 30]Se extensões parecerem demais, escreva uma função livre em vez disso, a ideia é a mesma:
func count<T>(_ items: [T], where predicate: (T) -> Bool) -> Int {
var n = 0
for item in items where predicate(item) {
n += 1
}
return n
}Uma vez que você consegue passar closures, a biblioteca padrão deixa de parecer mágica e começa a parecer um conjunto de padrões que você mesmo poderia escrever.
Desafio
MédioEscreva uma função livre partition(_ items: [Int], by predicate: (Int) -> Bool) -> ([Int], [Int]) que percorra o array uma vez e retorne uma tupla (matched, rest): elementos que satisfizeram o predicado e o restante, ambos na ordem original.
Leia duas linhas: um número inteiro min, e depois uma lista de inteiros separados por vírgula. Use sua função partition com um predicado que verifica n > min. Imprima:
matched: <...>rest: <...>
Cada lista unida com , (ou vazia quando não houver nada para imprimir).
Para a entrada 5 / 2,7,3,8,5, a saída é:
matched: 7,8
rest: 2,3,5Folha de consulta
Funções de ordem superior seguem um padrão consistente: aceitam um closure, chamam-no em um loop, retornam o resultado.
Como uma extensão:
extension Array {
func myMap<T>(_ transform: (Element) -> T) -> [T] {
var result: [T] = []
for item in self {
result.append(transform(item))
}
return result
}
}
[1, 2, 3].myMap { $0 * 10 } // [10, 20, 30]Como uma função livre:
func count<T>(_ items: [T], where predicate: (T) -> Bool) -> Int {
var n = 0
for item in items where predicate(item) {
n += 1
}
return n
}Uma função partition que retorna uma tupla de elementos correspondentes e não correspondentes:
func partition(_ items: [Int], by predicate: (Int) -> Bool) -> ([Int], [Int]) {
var matched: [Int] = []
var rest: [Int] = []
for item in items {
if predicate(item) { matched.append(item) }
else { rest.append(item) }
}
return (matched, rest)
}Experimente você mesmo
let min = Int(readLine()!)!
let nums = readLine()!.components(separatedBy: ",").map { Int($0)! }
// TODO: partition(_:by:) -> ([Int], [Int]); imprimir correspondentes e o restante
Esta lição inclui um quiz rápido. Comece a lição para respondê-lo e acompanhar seu progresso.
Todas as lições de Lógica e Fluxo
1Strings a Fundo
Contagem e ÍndicesCase e TrimBusca em StringsDivisão e JunçãoSubstituindo SubstringsRecapitulação - Verificação de Nome de Usuário4Conjuntos
Criando ConjuntosUnião e InterseçãoSubtração e Diferença SimétricaSubconjunto e SuperconjuntoRecapitulação - Filtro de Tags7Projeto - Monitor de Hábitos
Visão Geral do ProjetoMarcar como Concluído10Projeto - Mecanismo de Quiz
Visão Geral do ProjetoFazer Perguntas2Intervalos e Strides
Fechado vs Meio-AbertoStrideMétodos de IntervaloIntervalos no SwitchRecapitulação - Grade de Calendário5Funções de Ordem Superior Parte 1
MapFilterReduceEncadeando map, filter, reduceRecapitulação - Estatísticas de Palavras8Closures
Fundamentos de ClosuresTrailing ClosuresCapturando ValoresRetornando ClosuresHigher-Order PersonalizadasRecapitulação - Pipeline Builder