Το Enum είναι ένα πολύ χρήσιμο άρθρωμα που παρέχει ένα σύνολο αλγορίθμων για την εργασία με απαριθμήσιμα. Προσφέρει ταξινόμηση, φιλτράρισμα, ομαδοποίηση, καταμέτρηση, αναζήτηση, εύρεση ελάχιστων/μέγιστων τιμών και πολλά άλλα.
Γενικά, ένα απαριθμήσιμο είναι οποιαδήποτε δεδομένα πάνω στα οποία μπορείς να κάνεις επανάληψη, δηλαδή μια συλλογή. Στην Elixir, ένα απαριθμήσιμο είναι οποιοσδήποτε τύπος δεδομένων που υλοποιεί το πρωτόκολλο Enumerable. Τα πιο συνηθισμένα από αυτά είναι οι λίστες και οι χάρτες.
Πολλές συναρτήσεις του Enum δέχονται μια συνάρτηση ως όρισμα.
Enum.all?([1, 2, 3, 4, 5], fn x -> x > 3 end)
# => false
Οι πιο συνηθισμένες συναρτήσεις του Enum είναι οι map και reduce.
map/2Το Enum.map/2 σου επιτρέπει να αντικαταστήσεις κάθε στοιχείο ενός απαριθμήσιμου με ένα άλλο στοιχείο. Το δεύτερο όρισμα του Enum.map/2 είναι μια συνάρτηση που δέχεται το αρχικό στοιχείο και επιστρέφει το στοιχείο που θα το αντικαταστήσει.
reduce/3Το Enum.reduce/3 σου επιτρέπει να ανάγεις ολόκληρο το απαριθμήσιμο σε μία μόνο τιμή. Για να το πετύχεις αυτό, χρησιμοποιείται μια ειδική μεταβλητή που ονομάζεται συσσωρευτής. Ο συσσωρευτής μεταφέρει την ενδιάμεση κατάσταση της αναγωγής ανάμεσα στις επαναλήψεις.
Το δεύτερο όρισμα του Enum.reduce/3 είναι η αρχική τιμή του συσσωρευτή. Το τρίτο όρισμα είναι μια συνάρτηση που δέχεται ένα στοιχείο και έναν συσσωρευτή και επιστρέφει τη νέα τιμή του συσσωρευτή.
Όταν χρησιμοποιείς χάρτες με συναρτήσεις του Enum, ο χάρτης μετατρέπεται αυτόματα σε μια λίστα από 2 πλειάδες {key, value}.
Για να τον μετατρέψεις πίσω σε χάρτη, χρησιμοποίησε το Enum.into/2. Το Enum.into/2 είναι μια συνάρτηση που μετατρέπει ένα απαριθμήσιμο σε ένα collectable, δηλαδή σε οποιαδήποτε δομή δεδομένων που υλοποιεί το πρωτόκολλο Collectable. Μπορείς να το σκεφτείς ως το αντίθετο του Enum.reduce/3.
Το Enum έχει επίσης το Enum.into/3. Το Enum.into/3 είναι μια παραλλαγή του Enum.into/2 που δέχεται μια συνάρτηση μετασχηματισμού, η οποία εφαρμόζεται κατά τη μετατροπή του απαριθμήσιμου σε collectable.
Αντί να χρησιμοποιήσεις το Enum.into/3 ή το Enum.map/2 μαζί με το Enum.into/2 για να εφαρμόσεις έναν μετασχηματισμό (αντιστοίχιση) σε έναν χάρτη, μπορείς να χρησιμοποιήσεις και μια ειδική συνάρτηση, το Map.new/2. Λειτουργεί ακριβώς όπως το Enum.into/3, καθώς δέχεται ένα απαριθμήσιμο και μια συνάρτηση μετασχηματισμού, αλλά επιστρέφει πάντα έναν νέο χάρτη, αντί να σου επιτρέπει να επιλέξεις το collectable.
Διαχειρίζεσαι ένα ηλεκτρονικό κατάστημα μόδας. Η μεγάλη ετήσια έκπτωσή σου πλησιάζει, οπότε πρέπει να κάνεις απογραφή του αποθέματός σου για να σιγουρευτείς ότι όλα είναι έτοιμα.
Κάθε μεμονωμένο είδος στο απόθεμα αναπαρίσταται από ένα map, και ολόκληρο το απόθεμα είναι μια λίστα από τέτοια map.
%{
name: "White Shirt",
price: 40,
quantity_by_size: %{s: 3, m: 7, l: 8, xl: 4}
}
Υλοποίησε τη συνάρτηση sort_by_price/1. Θα πρέπει να παίρνει το απόθεμα και να το επιστρέφει ταξινομημένο κατά τιμή είδους, σε αύξουσα σειρά.
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: %{}}
# ]
Αφού ταξινόμησες το απόθεμά σου κατά τιμή, παρατήρησες ότι πρέπει να έκανες λάθος όταν έκανες την απογραφή και ξέχασες να συμπληρώσεις τις τιμές για μερικά είδη.
Υλοποίησε τη συνάρτηση with_missing_price/1. Θα πρέπει να παίρνει το απόθεμα και να επιστρέφει μια λίστα με τα είδη που δεν έχουν τιμή.
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: %{}}
# ]
Παρατήρησες ότι ονόματα ορισμένων ειδών περιέχουν μια λέξη που δεν θέλεις πια να χρησιμοποιείς. Τώρα πρέπει να ενημερώσεις όλα τα ονόματα των ειδών που περιέχουν αυτή τη λέξη.
Υλοποίησε τη συνάρτηση update_names/3. Θα πρέπει να παίρνει το απόθεμα, την παλιά λέξη που θέλεις να αφαιρέσεις και μια νέα λέξη που θέλεις να χρησιμοποιήσεις στη θέση της. Θα πρέπει να επιστρέφει μια λίστα με είδη που έχουν ενημερωμένα ονόματα.
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: %{}}
# ]
Μερικά είδη πουλούσαν ιδιαίτερα καλά, οπότε παρήγγειλες περισσότερα, σε όλα τα μεγέθη.
Υλοποίησε τη συνάρτηση increase_quantity/2. Θα πρέπει να παίρνει ένα μεμονωμένο είδος και έναν αριθμό n, και να επιστρέφει αυτό το είδος με την ποσότητα για κάθε μέγεθος αυξημένη κατά 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}
# }
Για να ξέρεις πόσο χώρο χρειάζεσαι στην αποθήκη σου, πρέπει να ξέρεις πόσα κομμάτια από κάθε είδος έχεις συνολικά.
Υλοποίησε τη συνάρτηση total_quantity/1. Θα πρέπει να παίρνει ένα μεμονωμένο είδος και να επιστρέφει πόσα κομμάτια έχεις συνολικά, σε οποιοδήποτε μέγεθος.
BoutiqueInventory.total_quantity(%{
name: "Red Shirt",
price: 62,
quantity_by_size: %{s: 3, m: 6, l: 5, xl: 2}
})
# => 16
Γράψου στο Exercism για να μάθεις και να κατακτήσεις Elixir με 58 έννοιες168 ασκήσεις και πραγματική καθοδήγηση από ανθρώπους, όλα δωρεάν.