Ένα MapSet είναι μια συλλογή μοναδικών τιμών, που αντιπροσωπεύει σύνολα στην Elixir.
Μπορεί να περιέχει τιμές οποιουδήποτε είδους, χωρίς την έννοια της διάταξης.
Σημείωσε ότι υπάρχει επίσης το module Set, αλλά είναι παρωχημένο προς όφελος του MapSet.
Μπορείς να δημιουργήσεις σύνολα χρησιμοποιώντας τα MapSet.new/0, MapSet.new/1 και MapSet.new/2, και να τα μετατρέψεις σε λίστες χρησιμοποιώντας το MapSet.to_list/1.
MapSet.new()
# => MapSet.new([])
MapSet.new([2, 3, 3, 3, 1, 1, 2, "hello"])
# => MapSet.new([1, 2, 3, "hello"])
MapSet.new([2, 3, 3, 3, 1, 1, 2], fn n -> 10 * n end)
# => MapSet.new([10, 20, 30])
[2, 3, 3, 3, 1, 1, 2] |> MapSet.new() |> MapSet.to_list()
# => [1, 2, 3]
Σημείωσε ότι, επειδή τα MapSet δεν έχουν την έννοια της διάταξης, το MapSet.to_list/1 δεν εγγυάται ότι επιστρέφει ταξινομημένη λίστα.
Μπορείς να προσθέσεις ή να αφαιρέσεις στοιχεία με τα MapSet.put/2 και MapSet.delete/2.
Μπορείς να ελέγξεις τα περιεχόμενα ενός συνόλου με τις συναρτήσεις MapSet.size/1, MapSet.member?/2, και να συγκρίνεις σύνολα με τα MapSet.equal?/2, MapSet.subset?/2 και MapSet.disjoint?/2.
a = MapSet.new([1, 10])
b = MapSet.new([1, 2, 3, 4, 5, 6, 7, 8, 9, 10])
MapSet.size(b)
# => 10
MapSet.member?(a, 10)
# => true
MapSet.subset?(a, b)
# => true
MapSet.disjoint?(a, b)
# => false
Τα MapSets μπορούν να συνδυαστούν με τα MapSet.union/2, MapSet.intersection/2, MapSet.difference/2 και MapSet.symmetric_difference/2.
a = MapSet.new([1, 10, 100])
b = MapSet.new([1, 2, 3, 4, 5, 6, 7, 8, 9, 10])
MapSet.union(a, b)
# => MapSet.new([1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 100])
MapSet.intersection(a, b)
# => MapSet.new([1, 10])
MapSet.difference(a, b)
# => MapSet.new([100])
MapSet.difference(b, a)
# => MapSet.new([2, 3, 4, 5, 6, 7, 8, 9])
MapSet.symmetric_difference(b, a)
# => MapSet.new([2, 3, 4, 5, 6, 7, 8, 9, 100])
Μπορείς να φιλτράρεις και να διαμερίσεις σύνολα με τα MapSet.filter/2, MapSet.reject/2 και MapSet.split_with/2.
a = MapSet.new([1, 2, 3, 4, 5, 6, 7, 8, 9, 10])
even = fn n -> rem(n, 2) == 0 end
MapSet.filter(a, even)
# => MapSet.new([2, 4, 6, 8, 10])
MapSet.reject(a, even)
# => MapSet.new([1, 3, 5, 7, 9])
MapSet.split_with(a, even)
# => {MapSet.new([2, 4, 6, 8, 10]), MapSet.new([1, 3, 5, 7, 9])}
Η νοσταλγία σου για τις κάρτες Blorkemon™️ δε δείχνει σημάδια κόπωσης, ξεκίνησες μάλιστα να τις συλλέγεις ξανά και βάζεις και τους φίλους σου να σε ακολουθήσουν.
Σε αυτή την άσκηση, μια συλλογή καρτών αναπαρίσταται από ένα MapSet, αφού οι διπλότυπες κάρτες δεν έχουν σημασία όταν ο στόχος σου είναι να αποκτήσεις όλες τις υπάρχουσες κάρτες.
Θέλεις πραγματικά να μπουν και οι φίλοι σου στην τρέλα με τα Blorkemon™️, και ο καλύτερος τρόπος είναι να ξεκινήσεις τη συλλογή τους δίνοντάς τους μία κάρτα.
Υλοποίησε τη GottaSnatchEmAll.new_collection, που μετατρέπει μια κάρτα σε συλλογή.
GottaSnatchEmAll.new_collection("Newthree")
# => MapSet.new(["Newthree"])
Μόλις αποκτήσεις μια συλλογή, αυτή αποκτά ζωή δική της και πρέπει να μεγαλώσει.
Υλοποίησε τη GottaSnatchEmAll.add_card, που παίρνει μια κάρτα και μια συλλογή και επιστρέφει μια πλειάδα με δύο τιμές: μία Boolean (λογική τιμή) που δείχνει αν η κάρτα ήταν ήδη στη συλλογή, και τη συλλογή με την κάρτα προσθεμένη.
GottaSnatchEmAll.add_card("Scientuna", MapSet.new(["Newthree"]))
# => {false, MapSet.new(["Newthree", "Scientuna"])}
Τώρα που οι φίλοι σου έχουν ξανατρελαθεί με τα Blorkemon™️, μπορείς να το εκμεταλλευτείς για να μεγαλώσεις τη δική σου συλλογή ανταλλάσσοντας κάρτες.
Δεν αξίζει να κάνεις κάθε ανταλλαγή, ενώ κάποιες δε γίνονται καθόλου. Δε μπορείς να ανταλλάξεις μια κάρτα που δεν έχεις, και δεν πρέπει να ανταλλάξεις μια κάρτα με κάποια που έχεις ήδη.
Υλοποίησε τη GottaSnatchEmAll.trade_card, που παίρνει δύο κάρτες προς ανταλλαγή (τη δική σου και τη δική τους) και την τρέχουσα συλλογή σου.
Η τιμή επιστροφής είναι μια πλειάδα με δύο τιμές: ένα boolean που δηλώνει αν η ανταλλαγή είναι εφικτή και αξίζει να γίνει, και τη συλλογή με την οποία θα κατέληγες αν έκανες την ανταλλαγή (ακόμα κι αν δεν είναι στην πραγματικότητα εφικτή).
GottaSnatchEmAll.trade_card("Scientuna", "Newthree", MapSet.new(["Scientuna"]))
# => {true, MapSet.new(["Newthree"])}
Βρίσκεις έναν παλιό σωρό κάρτες σε ένα παζάρι. Πρέπει να ταξινομήσεις τις κάρτες και να αφαιρέσεις τα διπλότυπα για να συγκρίνεις τη λίστα με τη συλλογή σου.
Υλοποίησε τη GottaSnatchEmAll.remove_duplicates, που θα ταξινομήσει μια λίστα καρτών και θα επιστρέψει μια λίστα με ταξινομημένες, μοναδικές κάρτες.
GottaSnatchEmAll.remove_duplicates(["Newthree", "Newthree", "Newthree", "Scientuna"])
# => ["Newthree", "Scientuna"]
Ώρα να νιώσεις καλά με τη συλλογή σου.
Υλοποίησε τη GottaSnatchEmAll.extra_cards, που παίρνει τη συλλογή σου και κάποια άλλη συλλογή, και επιστρέφει τον αριθμό των καρτών που δεν έχει η άλλη συλλογή.
GottaSnatchEmAll.extra_cards(MapSet.new(["Scientuna"]), MapSet.new(["Newthree", "Scientuna"]))
# => 0
Μαζεύεστε εσύ και οι φίλοι σου οι φανατικοί των Blorkemon™️ και αναρωτιέστε ποιες κάρτες είναι οι πιο κοινές.
Υλοποίησε τη GottaSnatchEmAll.boring_cards, που παίρνει μια λίστα από συλλογές και επιστρέφει μια λίστα με ταξινομημένες κάρτες που τις έχουν όλες οι συλλογές.
GottaSnatchEmAll.boring_cards([MapSet.new(["Scientuna"]), MapSet.new(["Newthree", "Scientuna"])])
# => ["Scientuna"]
Έχετε συλλογικά εσύ και οι φίλοι σου όλες τις κάρτες Blorkemon™️;
Υλοποίησε τη GottaSnatchEmAll.total_cards, που παίρνει μια λίστα από συλλογές και επιστρέφει τον συνολικό αριθμό των διαφορετικών καρτών σε όλες τις συλλογές.
GottaSnatchEmAll.total_cards([MapSet.new(["Scientuna"]), MapSet.new(["Newthree", "Scientuna"])])
# => 2
Ο ανιψιός σου θα έρθει σύντομα να σε επισκεφτεί και θέλεις να τον εντυπωσιάσεις. Στα παιδιά αρέσουν τα γυαλιστερά πράγματα, έτσι δεν είναι; Οι κάρτες Blorkemon™️ μπορούν να είναι γυαλιστερές!
Υλοποίησε τη GottaSnatchEmAll.split_shiny_cards, που παίρνει μια συλλογή και επιστρέφει μια πλειάδα με δύο λίστες ταξινομημένων καρτών: μία με όλες τις κάρτες που ξεκινούν με "Shiny" και μία με τις υπόλοιπες κάρτες.
GottaSnatchEmAll.split_shiny_cards(MapSet.new(["Newthree", "Scientuna", "Shiny Scientuna"]))
# => {["Shiny Scientuna"], ["Newthree", "Scientuna"]}
Γράψου στο Exercism για να μάθεις και να κατακτήσεις Elixir με 58 έννοιες168 ασκήσεις και πραγματική καθοδήγηση από ανθρώπους, όλα δωρεάν.