Enum é um módulo muito útil que fornece um conjunto de algoritmos para trabalhar com enumeráveis. Ele oferece ordenação, filtragem, agrupamento, contagem, busca, encontrar valores mínimos e 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 do 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 do Enum são map e reduce.
map/2O Enum.map/2 permite substituir cada elemento de um enumerável por outro elemento. O segundo argumento do Enum.map/2 é uma função que aceita o elemento original e retorna seu substituto.
reduce/3O Enum.reduce/3 permite reduzir todo o enumerável a um único valor. Para isso, usa-se uma variável especial chamada acumulador. O acumulador carrega o estado intermediário da redução entre as iterações.
O segundo argumento do Enum.reduce/3 é o valor inicial do acumulador. O terceiro argumento é uma função que aceita um elemento e um acumulador, e retorna o novo valor do acumulador.
Quando usamos mapas com funções do Enum, o mapa é automaticamente convertido em uma lista de 2 tuplas {key, value}.
Para transformá-lo de volta em um mapa, use Enum.into/2. O Enum.into/2 é uma função que transforma um enumerável em um coletável, ou seja, qualquer estrutura de dados que implemente o protocolo Collectable. Pode ser pensado como o oposto de Enum.reduce/3.
O Enum também tem Enum.into/3. O Enum.into/3 é uma variação do Enum.into/2 que aceita uma função de transformação a ser aplicada enquanto o enumerável é transformado em um 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 uma função dedicada, Map.new/2. Ela funciona exatamente como o Enum.into/3, no sentido de que aceita um enumerável e uma função de transformação, mas sempre retorna um novo mapa, em vez de nos deixar escolher o coletável.
Você administra uma boutique de moda online. Sua grande liquidação anual está chegando, então você precisa fazer um levantamento do inventário para garantir que está tudo pronto.
Cada item do inventário é representado por um mapa, e o inventário inteiro é uma lista desses mapas.
%{
name: "White Shirt",
price: 40,
quantity_by_size: %{s: 3, m: 7, l: 8, xl: 4}
}
Implemente a função sort_by_price/1. Ela deve receber o inventário e retorná-lo ordenado pelo preço do item, em 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 ordenar seu inventário por preço, você percebeu que deve ter cometido um erro ao fazer o levantamento e esqueceu de preencher o preço de alguns itens.
Implemente a função with_missing_price/1. Ela deve receber o inventário e retornar uma lista dos itens 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: %{}}
# ]
Você percebeu que alguns nomes de itens têm uma palavra que você não gosta mais de usar. Agora você precisa atualizar todos os nomes de itens que contêm essa palavra.
Implemente a função update_names/3. Ela deve receber o inventário, a palavra antiga que você quer remover e uma palavra nova que você quer usar no lugar. Ela deve retornar uma lista de itens 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 itens estavam vendendo especialmente bem, então você encomendou mais, em todos os tamanhos.
Implemente a função increase_quantity/2. Ela deve receber um único item e um número n e retornar esse item 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 saber de quanto espaço você precisa no seu depósito, você precisa saber quantas unidades de cada item você tem no total.
Implemente a função total_quantity/1. Ela deve receber um único item e retornar quantas peças você tem 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
Crie sua conta no Exercism para aprender e dominar Elixir com 58 conceitos168 exercícios e mentoria humana de verdade, tudo de graça.