Enum è un modulo molto utile che fornisce una serie di algoritmi per lavorare con gli enumerabili. Offre ordinamento, filtraggio, raggruppamento, conteggio, ricerca, ricerca dei valori min/max e molto altro.
In generale, un enumerabile è qualsiasi dato su cui si può iterare, una collezione. In Elixir, un enumerabile è qualsiasi tipo di dato che implementa il protocollo Enumerable. I più comuni sono gli array e le mappe.
Molte funzioni di Enum accettano una funzione come argomento.
Enum.all?([1, 2, 3, 4, 5], fn x -> x > 3 end)
# => false
Le funzioni di Enum più comuni sono map e reduce.
map/2Enum.map/2 ti permette di sostituire ogni elemento in un enumerabile con un altro elemento. Il secondo argomento di Enum.map/2 è una funzione che accetta l'elemento originale e restituisce il suo sostituto.
reduce/3Enum.reduce/3 ti permette di ridurre l'intero enumerabile a un singolo valore. Per ottenere questo, si usa una variabile speciale chiamata accumulatore. L'accumulatore porta con sé lo stato intermedio della riduzione tra un'iterazione e l'altra.
Il secondo argomento di Enum.reduce/3 è il valore iniziale dell'accumulatore. Il terzo argomento è una funzione che accetta un elemento e un accumulatore, e restituisce il nuovo valore per l'accumulatore.
Quando usi le mappe con le funzioni di Enum, la mappa viene automaticamente convertita in un array di 2 tuple {key, value}.
Per trasformarla di nuovo in una mappa, usa Enum.into/2. Enum.into/2 è una funzione che trasforma un enumerabile in una struttura collezionabile, cioè qualsiasi struttura dati che implementa il protocollo Collectable. Può essere pensata come l'opposto di Enum.reduce/3.
Enum ha anche Enum.into/3. Enum.into/3 è una variante di Enum.into/2 che accetta una funzione di trasformazione da applicare mentre trasforma l'enumerabile in una struttura collezionabile.
Invece di usare Enum.into/3 o Enum.map/2 più Enum.into/2 per applicare una trasformazione (mappatura) a una mappa, possiamo anche usare una funzione dedicata, Map.new/2. Funziona esattamente come Enum.into/3, nel senso che accetta un enumerabile e una funzione di trasformazione, ma restituisce sempre una nuova mappa invece di permetterci di scegliere una struttura collezionabile.
Gestisci una boutique di moda online. I tuoi grandi saldi annuali stanno per iniziare, quindi devi fare il punto sull'inventario per assicurarti che sia tutto pronto.
Un singolo articolo dell'inventario è rappresentato da una mappa, e l'intero inventario è un array di mappe di questo tipo.
%{
name: "White Shirt",
price: 40,
quantity_by_size: %{s: 3, m: 7, l: 8, xl: 4}
}
Implementa la funzione sort_by_price/1. Deve prendere l'inventario e restituirlo ordinato per prezzo dell'articolo, in ordine 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: %{}}
# ]
Dopo aver ordinato l'inventario per prezzo, hai notato di aver commesso un errore mentre facevi l'inventario e di aver dimenticato di inserire il prezzo di alcuni articoli.
Implementa la funzione with_missing_price/1. Deve prendere l'inventario e restituire un array di articoli che non hanno un prezzo.
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: %{}}
# ]
Hai notato che alcuni nomi di articoli contengono una parola che non vuoi più usare. Ora devi aggiornare tutti i nomi degli articoli che contengono quella parola.
Implementa la funzione update_names/3. Deve prendere l'inventario, la vecchia parola che vuoi rimuovere e una nuova parola da usare al suo posto. Deve restituire un array di articoli con i nomi aggiornati.
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: %{}}
# ]
Alcuni articoli vendevano particolarmente bene, quindi ne hai ordinati altri, in tutte le taglie.
Implementa la funzione increase_quantity/2. Deve prendere un singolo articolo e un numero n, e restituire quell'articolo con la quantità di ogni taglia aumentata di 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}
# }
Per sapere quanto spazio ti serve in magazzino, devi sapere quanti pezzi hai in totale per ogni articolo.
Implementa la funzione total_quantity/1. Deve prendere un singolo articolo e restituire quanti pezzi hai in totale, in qualsiasi taglia.
BoutiqueInventory.total_quantity(%{
name: "Red Shirt",
price: 62,
quantity_by_size: %{s: 3, m: 6, l: 5, xl: 2}
})
# => 16
Iscriviti a Exercism per imparare e padroneggiare Elixir con 58 concetti168 esercizi e il mentoring di persone reali, tutto gratis.