Percursos
/
Elixir
Elixir
/
Exercícios
/
Inventário da boutique
Inventário da boutique

Inventário da boutique

Exercício de aprendizagem

Introdução

Enum

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/2

Enum.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/3

Enum.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.

Trabalhar com mapas

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.

Mapear mapas

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.

Instruções

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}
}

1. Ordenar os artigos por preço

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: %{}}
#    ]

2. Encontrar todos os artigos sem preço

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: %{}}
#    ]

3. Atualizar os nomes dos artigos

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: %{}}
#    ]

4. Aumentar a quantidade do artigo

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}
#    }

5. Calcular a quantidade total do artigo

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
Editar via GitHub A ligação abre numa nova janela ou separador
Elixir Exercism

Estás pronto para começar Inventário da boutique?

Inscreve-te no Exercism para aprenderes e dominares Elixir com 58 conceitos168 exercícios, e mentoria humana real, tudo grátis.