Escrito por Reinder de Vries, em 12 de julho de 2020 em Desenvolvimento de aplicativos, o Swift

FlatMap e CompactMap Explicado na Swift

Swift tem um monte de funções que são úteis para a transformação de conjuntos e sequências. Neste tutorial, vamos discutir map(_:), flatMap(_:) e compactMap(_:).

aqui está o que vamos nos concentrar:

  1. Como map(_:) transforma um conjunto ou seqüência de aplicação de um fechamento
  2. Como flatMap(_:) pode achatar um array de entrada, depois de chamar map(_:)
  3. Como compactMap(_:) remove nil a partir de uma matriz de entrada

Em um tutorial anterior, discutimos como você pode usar filter(_:) e reduce(_:). Essas funções de ordem superior são super úteis para transformar coleções, de maneira concisa e perspicaz.

pronto? Vamos.

  1. Usando a Função de Mapa na Swift
  2. Usando o FlatMap Função
  3. Usando o CompactMap Função
  4. Por que Usar FlatMap e CompactMap?
  5. Leitura Adicional

ainda não está familiarizado com fechamentos ou funções de ordem superior? Certifique-se de ler sobre os primeiros:

  • O melhor Guia para tampas de Swift
  • Mapa, Reduzir e Filtro de Swift

Usando a Função de Mapa na Swift

Como uma rápida atualização sobre funções de ordem superior na Swift, o nosso ponto de partida é o map(_:) função. Esta função aplica uma transformação a cada um dos elementos em uma sequência, como uma matriz ou dicionário.

aqui está um exemplo:

let numbers =
let result = numbers.mapa({ $0 * $0 })
de impressão(resultado)
Ocultar avisos

Vamos quebrar esse baixo:

Primeiro, estamos criando um array numbers com alguns valores inteiros. Em seguida, a função map(_:) é chamada em numbers e seu resultado é atribuído a result.

a função map(_:) tem um parâmetro, um encerramento, que retorna o resultado de . O corresponde ao primeiro parâmetro do encerramento, ou seja, o número de numbers que está sendo transformado.

estamos calculando o quadrado de cada número em numbers. Em essência, a operação é chamada em todos os números em numbers, e a matriz resultante é atribuída a result. Você está transformando – ou “mapeando” – uma matriz em outra.

transformar uma matriz com map(_:) é semelhante a usar um loop for, mas muito mais conciso. Assim:

let numbers = var result = ()for number in numbers { result += }print(result)

aqui está outra maneira de olhar para ele. Com map(_:) , a matriz de entrada de números é transformada em outra matriz de números. Assim:

2 => 2 * 2 => 43 => 3 * 3 => 94 => 4 * 4 => 165 => 5 * 5 => 25

funções como map(_:) são chamadas de funções de ordem superior, porque elas assumem uma função como entrada em oposição aos valores comuns. Funções de ordem superior também podem produzir funções, o que é útil para um paradigma de programação chamado programação funcional.Tecnicamente, você pode chamar funções de ordem superior como map(_:) em qualquer sequência. Isso inclui coleções como arrays, dicionários e conjuntos, intervalos como 1...100 e os chamados iteradores. Qualquer coisa que se pareça com uma” lista ” de valores, basicamente.

discutiremos por que as funções de ordem superior são úteis no final deste tutorial. Vamos primeiro aprender sobre flatMap(_:)e compactMap(_:).

seja contratado como desenvolvedor iOS

Aprenda a criar aplicativos iOS 14 com Swift 5

Inscreva-se no meu curso de desenvolvimento iOS e aprenda como iniciar sua carreira como desenvolvedor iOS profissional.

usando a função FlatMap

a função flatMap(_:) é semelhante a map(_:), exceto que” achata ” a matriz resultante. Aqui está um exemplo:

vamos números=,,]
deixe resultado = números.flatMap({ $0 })
print(resultado)
Ocultar avisos

O código acima começa com uma aninhadas matriz de inteiros. A matriz numbers consiste em uma matriz de 3 matrizes, cada uma contendo 3 números.

o encerramento { } simplesmente retorna o primeiro argumento do encerramento, ou seja, as matrizes aninhadas individuais. Nenhuma transformação ou operação está acontecendo. Quando você liga para flatMap(_:) na matriz numbers, em vez de map(_:), você acaba com uma matriz achatada de números individuais. Ao contrário da matriz de entrada numbers, a matriz de resultados não contém matrizes aninhadas!

vejamos outro exemplo. Imagine que você está trabalhando com 4 grupos de girafas, e quer criar um único grupo de girafas que são mais altas do que uma certa altura. Veja como você faz isso:

vamos girafas=,,]
deixe mais alto = girafas.flatMap ({ $0.filtro({ $0 > 10 }) })
de impressão(mais alto)
Ocultar avisos

Veja como giraffes contém uma matriz de matrizes? No código acima, a função filter(_:) é chamada em cada matriz aninhada dentro giraffes. Nós só queremos inteiros (girafas!) que são maiores que 10. As matrizes resultantes são achatadas em uma matriz” plana ” e atribuídas a tallest.

considere o que aconteceria se tivéssemos usado map(_:) em vez de flatMap(_:). A matriz resultante não seria achatada. Em vez disso, seria isso:

, , ]

é importante observar que a função flatMap(_:) chama map(_:) nos itens da matriz primeiro e depois o achata. É por isso que algo como o seguinte não funciona:

let numbers = , , ]let result = numbers.flatMap({  * 2 })

no código acima, o refere-se às matrizes dentro dos números. Multiplicar um array por dois é impossível, então é por isso que esse código não funciona.

é inteligente pensar em flatmapping como ver uma matriz em uma dimensão a menos. Você começa com uma matriz bidimensional e acaba com uma matriz unidimensional após flatMap(_:).

que tal usar flatMap(_:) com opções? Vamos ver o próximo.

o nome “mapa compacto” é baseado na ideia de que remover itens nil de uma matriz torna a matriz mais compacta. Da mesma forma, o nome “mapa plano” vem do achatamento da matriz. E “mapeamento” é um conceito da matemática, onde você associa os valores em um conjunto com outro conjunto.

usando a função CompactMap

a função compactMap(_:) remove nil valores da matriz de entrada. É super útil quando se trabalha com opções.

Antes Do Swift 4.1, a função flatMap(_:) (acima) também pode ser usada para filtrar valores nil de matrizes achatadas. Desde Swift 4.1+, Agora você usa o explícito compactMap(_:) para esse fim.

aqui está um exemplo:

let numbers =
let result = numbers.como criar uma conta no Facebook?)
ocultar avisos

veja o que acontece? A parte mais importante do código é Int(). Isso leva uma string individual de numbers com e tenta converter para um inteiro, com o inicializador Int().

this Int() initializer is failable: it can return nil – an optional – so its return type is Int?. Como resultado, o tipo de retorno da transformação de mapeamento é – uma matriz de inteiros opcionais.

a função compactMap(_:) remove automaticamente nil elementos da matriz retornada, após chamar map(_:) nela. Como tal, seu tipo de retorno não é opcional.

no código acima, o tipo de result é . Se você tivesse usado map(_:) , o tipo de retorno teria sido . E você precisaria de uma etapa extra para desembrulhar os valores da matriz, para trabalhar com eles.

por que usar FlatMap e CompactMap?

antes de discutirmos os casos de Uso do mundo real de flatmap e compactmap, vamos fazer uma rápida recapitulação dessas funções de ordem superior e seus propósitos.

  1. O map(_:) função aplica-se a um fechamento para uma entrada de coleta, e retorna a transformada de recolha
  2. O flatMap(_:) função faz o mesmo, e também achata a coleção resultante
  3. O compactMap(_:) função faz o mesmo que map(_:), e também remove nil a partir de uma coleção resultante

Trabalhando com map(_:), flatMap(_:) e compactMap(_:) em abstrato torna, às vezes, é muito difícil imaginar o uso prático dos casos. Vamos discutir por que você gostaria de usá-los.

usar funções como map (_:) para aplicar transformações a sequências tem algumas vantagens:

  • é mais conciso do que usar um loop for, porque você não precisa de variáveis temporárias e um bloco for in { } de várias linhas.
  • você normalmente pode escrever uma chamada para map(_:) em uma linha, o que (geralmente) torna seu código mais legível.
  • funções como map(_:) podem ser encadeadas, para que você possa aplicar várias transformações a uma sequência, uma por uma.

em geral, as funções de ordem superior são úteis porque permitem aplicar uma função a uma sequência de valores. Em vez de codificar a transformação processualmente, você pode apenas aplicar a função e obter um resultado de volta.

o caso de uso mais prático para flatMap(_:) está trabalhando com valores de entrada agrupados ou aninhados, mas o valor de saída desejado precisa ser unidimensional.

você pode, em um aplicativo de música, por exemplo, ter 3 matrizes: músicas, artistas e listas de reprodução. Você os combina em uma matriz, chama flatMap(_:) nela, seleciona as músicas, artistas e listas de reprodução para as quais isFavorite é true e acaba com uma lista plana de itens que foram favoritos.

um caso de uso prático para compactMap(_:) está trabalhando com uma transformação que pode retornar nil. Você salva algumas etapas triviais deixando compactMap(_:) filtrar nil valores imediatamente. Um benefício adicional é o tipo de retorno não opcional de compactMap(_:); a função filter(_:), em comparação, teria retornado um valor opcional se você filtrasse nil.

você pode combinar flatMap(_:) e compactMap(_:), e até mesmo filter(_:)ou reduce(_:_:). Imagine que você está construindo um aplicativo de mídia social. Você deseja construir uma linha do tempo de postagens para um usuário. Você usa 3 consultas para selecionar IDs de postagem para o usuário, por exemplo, de postagens de seguidores, anúncios e tópicos de tendência.

  • Você pode usar map(_:) para expandir essas Identificações em real Post objetos
  • Você pode usar flatMap(_:) para achatar os 3 grupos em uma coleção
  • Você pode usar compactMap(_:) para rejeitar mensagens que não poderia ser expandido

Puro!

seja contratado como desenvolvedor iOS

Aprenda a criar aplicativos iOS 14 com Swift 5

Inscreva-se no meu curso de desenvolvimento iOS e aprenda como iniciar sua carreira como desenvolvedor iOS profissional.

Leitura Adicional

vale a pena aprender sobre map(_:), flatMap(_:) e compactMap(_:), porque tornam o código mais conciso e legível. Você pode adicionar programação mais funcional ao código do seu aplicativo. Depois de se acostumar com eles, você não pode acreditar que poderia fazer seu trabalho sem eles.

especialmente as diferenças entre map(_:), flatMap(_:) e compactMap(_:) valem a pena apontar. O primeiro aplica uma transformação a uma sequência, o segundo nivela a matriz resultante e o terceiro remove os valores nil antes de retornar seu resultado. Da hora!

Deixe uma resposta

O seu endereço de email não será publicado.