Enum é um módulo muito útil que fornece um conjunto de algoritmos para trabalhar com enumeráveis. Oferece ordenação, filtragem, agrupamento, contagem, pesquisa, procura de valores mínimos/máximos e muito mais.
Em geral, um enumerável é qualquer dado sobre o qual se pode iterar, uma coleção. Em Elixir, um enumerável é qualquer tipo de dados que implemente o protocolo Enumerable. Os mais comuns são as listas e os mapas.
Muitas funções de Enum aceitam uma função como argumento.
Enum.all?([1, 2, 3, 4, 5], fn x -> x > 3 end)
# => false
As funções mais comuns de Enum são map e reduce.
map/2Enum.map/2 permite-te substituir cada elemento de um enumerável por outro elemento. O segundo argumento de Enum.map/2 é uma função que aceita o elemento original e devolve o seu substituto.
reduce/3Enum.reduce/3 permite-te reduzir todo o enumerável a um único valor. Para isso, é usada uma variável especial chamada acumulador. O acumulador transporta o estado intermédio da redução entre iterações.
O segundo argumento de Enum.reduce/3 é o valor inicial do acumulador. O terceiro argumento é uma função que aceita um elemento e um acumulador e devolve o novo valor do acumulador.
Ao usar mapas com funções de Enum, o mapa é automaticamente convertido numa lista de 2 tuplos {key, value}.
Para o transformar novamente num mapa, usa Enum.into/2. Enum.into/2 é uma função que transforma um enumerável num coletável, ou seja, qualquer estrutura de dados que implemente o protocolo Collectable. Pode ser encarada como o oposto de Enum.reduce/3.
Enum também tem Enum.into/3. Enum.into/3 é uma variação de Enum.into/2 que aceita uma função de transformação a aplicar enquanto transforma o enumerável num coletável.
Em vez de usar Enum.into/3 ou Enum.map/2 mais Enum.into/2 para aplicar uma transformação (mapeamento) a um mapa, também podemos usar a função dedicada Map.new/2. Funciona exatamente como Enum.into/3, no sentido em que aceita um enumerável e uma função de transformação, mas devolve sempre um novo mapa em vez de nos deixar escolher um coletável.
Tens uma boutique de moda online. A tua grande promoção anual está a chegar, por isso precisas de fazer o inventário para garantir que está tudo pronto.
Cada artigo do inventário é representado por um mapa, e o inventário completo é uma lista desses mapas.
%{
name: "White Shirt",
price: 40,
quantity_by_size: %{s: 3, m: 7, l: 8, xl: 4}
}
Implementa a função sort_by_price/1. Deve receber o inventário e devolvê-lo ordenado pelo preço dos artigos, por ordem crescente.
BoutiqueInventory.sort_by_price([
%{price: 65, name: "Maxi Brown Dress", quantity_by_size: %{}},
%{price: 50, name: "Red Short Skirt", quantity_by_size: %{}},
%{price: 50, name: "Black Short Skirt", quantity_by_size: %{}},
%{price: 20, name: "Bamboo Socks Cats", quantity_by_size: %{}}
])
# => [
# %{price: 20, name: "Bamboo Socks Cats", quantity_by_size: %{}},
# %{price: 50, name: "Red Short Skirt", quantity_by_size: %{}},
# %{price: 50, name: "Black Short Skirt", quantity_by_size: %{}},
# %{price: 65, name: "Maxi Brown Dress", price: 65, quantity_by_size: %{}}
# ]
Depois de ordenares o inventário por preço, reparaste que deves ter cometido um erro ao fazer o inventário e esqueceste-te de preencher os preços de alguns artigos.
Implementa a função with_missing_price/1. Deve receber o inventário e devolver uma lista dos artigos que não têm preço.
BoutiqueInventory.with_missing_price([
%{price: 40, name: "Black T-shirt", quantity_by_size: %{}},
%{price: nil, name: "Denim Pants", quantity_by_size: %{}},
%{price: nil, name: "Denim Skirt", quantity_by_size: %{}},
%{price: 40, name: "Orange T-shirt", quantity_by_size: %{}}
])
# => [
# %{price: nil, name: "Denim Pants", quantity_by_size: %{}},
# %{price: nil, name: "Denim Skirt", quantity_by_size: %{}}
# ]
Reparaste que alguns nomes de artigos têm uma palavra que já não gostas de usar. Agora precisas de atualizar todos os nomes de artigos com essa palavra.
Implementa a função update_names/3. Deve receber o inventário, a palavra antiga que queres remover e uma palavra nova que queres usar em vez dela. Deve devolver uma lista de artigos com os nomes atualizados.
BoutiqueInventory.update_names(
[
%{price: 40, name: "Black T-shirt", quantity_by_size: %{}},
%{price: 70, name: "Denim Pants", quantity_by_size: %{}},
%{price: 65, name: "Denim Skirt", quantity_by_size: %{}},
%{price: 40, name: "Orange T-shirt", quantity_by_size: %{}}
],
"T-shirt",
"Tee"
)
# => [
# %{price: 40, name: "Black Tee", quantity_by_size: %{}},
# %{price: 70, name: "Denim Pants", quantity_by_size: %{}},
# %{price: 65, name: "Denim Skirt", quantity_by_size: %{}},
# %{price: 40, name: "Orange Tee", quantity_by_size: %{}}
# ]
Alguns artigos estavam a vender especialmente bem, por isso encomendaste mais, em todos os tamanhos.
Implementa a função increase_quantity/2. Deve receber um único artigo e um número n, e devolver esse artigo com a quantidade de cada tamanho aumentada em n.
BoutiqueInventory.increase_quantity(
%{
name: "Polka Dot Skirt",
price: 68,
quantity_by_size: %{s: 3, m: 5, l: 3, xl: 4}
},
6
)
# => %{
# name: "Polka Dot Skirt",
# price: 68,
# quantity_by_size: %{l: 9, m: 11, s: 9, xl: 10}
# }
Para saberes quanto espaço precisas no teu armazém, tens de saber quantas unidades tens de cada artigo no total.
Implementa a função total_quantity/1. Deve receber um único artigo e devolver quantas peças tens no total, em qualquer tamanho.
BoutiqueInventory.total_quantity(%{
name: "Red Shirt",
price: 62,
quantity_by_size: %{s: 3, m: 6, l: 5, xl: 2}
})
# => 16
Inscreve-te no Exercism para aprenderes e dominares Elixir com 58 conceitos168 exercícios, e mentoria humana real, tudo grátis.