Η έννοια "Ζεύγη και Λεξικά" συζήτησε τα βασικά του τύπου λεξικού της Julia.
Επειδή τα Dict αποτελούν έναν σημαντικό και συχνά χρησιμοποιούμενο τύπο συλλογής, υπάρχουν επίσης πολλές συναρτήσεις για τον χειρισμό τους.
Ο απλούστερος τρόπος για να ανακτήσεις μια καταχώριση είναι μέσω του κλειδιού (όπως σε πολλές γλώσσες).
Ωστόσο, το να ζητήσεις ένα κλειδί που δεν υπάρχει προκαλεί KeyError.
julia> d = Dict(i => ('a':'c')[i] for i in 1:3)
Dict{Int64, Char} with 3 entries:
2 => 'b'
3 => 'c'
1 => 'a'
julia> d[2]
'b': ASCII/Unicode U+0062 (category Ll: Letter, lowercase)
# missing key
julia> d[4]
ERROR: KeyError: key 4 not found
Θα μπορούσαμε να ελέγξουμε αν υπάρχει το κλειδί πριν προσπαθήσουμε να το ανακτήσουμε (με κάτι σαν haskey(d, 4)), αλλά μπορεί να είναι χρήσιμο να πάρεις απλώς μια προεπιλεγμένη τιμή για κλειδιά που λείπουν.
Γι' αυτό, έχουμε τη συνάρτηση get() και τη μεταλλακτική παραλλαγή get!().
Αυτές διαφέρουν ως προς το αν ένα κλειδί που "λείπει" προστίθεται στο Dict.
julia> get(d, 4, '!')
'!': ASCII/Unicode U+0021 (category Po: Punctuation, other)
# get() leaves Dict unchanged
julia> d
Dict{Int64, Char} with 3 entries:
2 => 'b'
3 => 'c'
1 => 'a'
julia> get!(d, 4, '!')
'!': ASCII/Unicode U+0021 (category Po: Punctuation, other)
# get!() adds new key to Dict
julia> d
Dict{Int64, Char} with 4 entries:
4 => '!'
2 => 'b'
3 => 'c'
1 => 'a'
Είδαμε στην προηγούμενη έννοια ότι η delete!() αφαιρεί μια καταχώριση με βάση το κλειδί.
Αυτό μπορεί να συνδυαστεί με την ανάκτηση της τιμής, χρησιμοποιώντας τη συνάρτηση pop!().
julia> d
Dict{Int64, Char} with 4 entries:
4 => '!'
2 => 'b'
3 => 'c'
1 => 'a'
# popped value is returned
julia> pop!(d, 3)
'c': ASCII/Unicode U+0063 (category Ll: Letter, lowercase)
# Dict is shrunk
julia> d
Dict{Int64, Char} with 3 entries:
4 => '!'
2 => 'b'
1 => 'a'
Η επανάληψη πάνω σε ένα Dict από προεπιλογή αποδίδει ζεύγη key => value.
Τα συστατικά είναι προσβάσιμα με τη συνήθη ονοματολογία .first και .second.
# d is from the previous example
julia> [(kv.first, kv.second) for kv in d]
3-element Vector{Tuple{Int64, Char}}:
(4, '!')
(2, 'b')
(1, 'a')
Συχνά, θέλουμε να χρησιμοποιήσουμε μόνο τα κλειδιά ή μόνο τις τιμές, κάτι που είναι εύκολο.
julia> [k for k in keys(d)]
3-element Vector{Int64}:
4
2
1
julia> [v for v in values(d)]
3-element Vector{Char}:
'!': ASCII/Unicode U+0021 (category Po: Punctuation, other)
'b': ASCII/Unicode U+0062 (category Ll: Letter, lowercase)
'a': ASCII/Unicode U+0061 (category Ll: Letter, lowercase)
Ο συνδυασμός δύο Dict μπορεί να είναι χρήσιμος, αλλά πρέπει να είμαστε σαφείς για το τι σκοπεύουμε να κάνουμε με κλειδιά που υπάρχουν σε περισσότερες από μία εισόδους.
Οι συναρτήσεις merge() και merge!() συνδυάζουν έναν αυθαίρετο αριθμό από Dict που δίνονται, με σειρά από αριστερά προς τα δεξιά.
Οι τιμές των υπαρχόντων κλειδιών απλώς αντικαθίστανται, οπότε το δεξιότερο Dict "κερδίζει".
julia> d3 = Dict("color" => "red", "shape" => "circle")
Dict{String, String} with 2 entries:
"shape" => "circle"
"color" => "red"
julia> d4 = Dict("color" => "blue", "coords" => (3, 2))
Dict{String, Any} with 2 entries:
"color" => "blue"
"coords" => (3, 2)
# color from d3 is lost
julia> merge(d3, d4)
Dict{String, Any} with 3 entries:
"shape" => "circle"
"color" => "blue"
"coords" => (3, 2)
Οι συναρτήσεις mergewith() και mergewith!() μάς επιτρέπουν να δώσουμε μια συνάρτηση ως πρώτο όρισμα, για να ορίσουμε πώς θα συγχωνεύονται τα κλειδιά που επαναλαμβάνονται.
Η πρόσθεση είναι ένα απλό παράδειγμα.
julia> d5 = Dict("color" => "red", "area" => 3)
Dict{String, Any} with 2 entries:
"area" => 3
"color" => "red"
julia> d6 = Dict("shape" => "circle", "area" => 5)
Dict{String, Any} with 2 entries:
"shape" => "circle"
"area" => 5
# area values are added, not overwritten
julia> mergewith(+, d5, d6)
Dict{String, Any} with 3 entries:
"shape" => "circle"
"area" => 8
"color" => "red"
Σημείωσε ότι οι συναρτήσεις mergewith αποτελούν ένα καλό παράδειγμα συναρτήσεων υψηλότερης τάξης σε δράση.
Η Mecha Munch™, μια εταιρεία που αυτοματοποιεί τις αγορές τροφίμων, μόλις σε προσέλαβε για να δουλέψεις στην εφαρμογή παραγγελιών της. Η ομάδα σου έχει αναλάβει να φτιάξει ένα MVP (ελάχιστο βιώσιμο προϊόν) που διαχειρίζεται όλες τις βασικές λειτουργίες του καλαθιού αγορών, επιτρέποντας στους χρήστες να προσθέτουν, να αφαιρούν και να ταξινομούν τις παραγγελίες τροφίμων τους. Ευτυχώς, μια άλλη ομάδα αναλαμβάνει όλα τα ζητήματα με τα χρήματα και την ολοκλήρωση της παραγγελίας!
Το MVP πρέπει να επιτρέπει στον χρήστη να προσθέτει προϊόντα στο καλάθι αγορών του. Αυτό μπορεί να είναι ένα μεμονωμένο προϊόν ή πολλά προϊόντα μαζί. Επειδή πρόκειται για MVP, η ποσότητα του προϊόντος δηλώνεται με επαναλήψεις. Αν ένας χρήστης θέλει να προσθέσει 2 Πορτοκάλια, το "Oranges" θα εμφανίζεται δύο φορές στο iterable εισόδου. Αν ο χρήστης έχει ήδη το προϊόν στο καλάθι του, η ποσότητα στο καλάθι πρέπει να αυξηθεί κατά 1. Αν το προϊόν είναι νέο στο καλάθι, πρέπει να προστεθεί με ποσότητα 1.
Δημιούργησε τη συνάρτηση add_items!(<cart>, <items>), που παίρνει ως ορίσματα ένα λεξικό για το καλάθι και ένα iterable με τα προϊόντα προς προσθήκη.
Πρέπει να επιστρέφει το ενημερωμένο λεξικό του καλαθιού αγορών για τον χρήστη.
julia> additems!(Dict("Banana" => 3, "Apple" => 2, "Orange" => 1),
("Apple", "Apple", "Orange", "Apple", "Banana"))
Dict{String, Int64} with 3 entries:
"Apple" => 5
"Orange" => 2
"Banana" => 4
julia> additems!(Dict("Banana" => 3, "Apple" => 2, "Orange" => 1),
["Banana", "Orange", "Blueberries", "Banana"])
Dict{String, Int64} with 4 entries:
"Blueberries" => 1
"Apple" => 2
"Orange" => 2
"Banana" => 5
Η εφαρμογή έχει μια ενότητα "ιδέες" που είναι γεμάτη με έτοιμες συνταγές από διάφορες κουζίνες. Ο χρήστης μπορεί να διαλέξει οποιαδήποτε από αυτές τις συνταγές και να προστεθούν αυτόματα όλα τα υλικά της στο καλάθι αγορών του. Ο υπεύθυνος του έργου σου ζήτησε να δημιουργήσεις έναν τρόπο για να επεξεργάζεσαι αυτές τις συνταγές της ενότητας "ιδέες", αφού η ομάδα περιεχομένου αλλάζει συνεχώς υλικά και ποσότητες.
Δημιούργησε τη συνάρτηση update_recipes!(<ideas>, <updates>), που παίρνει ως ορίσματα ένα λεξικό "ιδεών" και ένα λεξικό με ενημερώσεις συνταγών.
Η συνάρτηση πρέπει να επιστρέφει το ενημερωμένο λεξικό "ιδεών".
julia>update_recipes!(
Dict("Banana Bread" => Dict("Banana" => 1, "Apple" => 1, "Walnuts" => 1, "Flour" => 1, "Eggs" => 2, "Butter" => 1),
"Raspberry Pie" => Dict("Raspberry" => 1, "Orange" => 1, "Pie Crust" => 1, "Cream Custard" => 1)),
Dict("Banana Bread" => Dict("Banana" => 4, "Walnuts" => 2, "Flour" => 1, "Butter" => 1, "Milk" => 2, "Eggs" => 3))
)
Dict{String, Dict{String, Int64}} with 2 entries:
"Raspberry Pie" => Dict("Cream Custard"=>1, "Raspberry"=>1, "Orange"=>1, "Pie Crust"=>1)
"Banana Bread" => Dict("Eggs"=>3, "Flour"=>1, "Milk"=>2, "Butter"=>1, "Walnuts"=>2, "Banana"=>4)
julia> update_recipes!(
Dict("Banana Bread" => Dict("Banana" => 1, "Apple" => 1, "Walnuts" => 1, "Flour" => 1, "Eggs" => 2, "Butter" => 1),
"Raspberry Pie" => Dict("Raspberry" => 1, "Orange" => 1, "Pie Crust" => 1, "Cream Custard" => 1),
"Pasta Primavera" => Dict("Eggs" => 1, "Carrots" => 1, "Spinach" => 2, "Tomatoes" => 3, "Parmesan" => 2, "Milk" => 1, "Onion" => 1)),
Dict("Raspberry Pie" => Dict("Raspberry" => 3, "Orange" => 1, "Pie Crust" => 1, "Cream Custard" => 1, "Whipped Cream" => 2),
"Pasta Primavera" => Dict("Eggs" => 1, "Mixed Veggies" => 2, "Parmesan" => 2, "Milk" => 1, "Spinach" => 1, "Bread Crumbs" => 1),
"Blueberry Crumble" => Dict("Blueberries" => 2, "Whipped Creme" => 2, "Granola Topping" => 2, "Yogurt" => 3))
)
Dict{String, Dict{String, Int64}} with 4 entries:
"Raspberry Pie" => Dict("Raspberry"=>3, "Orange"=>1, "Pie Crust"=>1, "Cream Custard"=>1, "Whipped Cream"=>2)
"Pasta Primavera" => Dict("Eggs"=>1, "Mixed Veggies"=>2, "Parmesan"=>2, "Milk"=>1, "Spinach"=>1, "Bread Crumbs"=>1)
"Blueberry Crumble" => Dict("Blueberries"=>2, "Whipped Creme"=>2, "Granola Topping"=>2, "Yogurt"=>3)
"Banana Bread" => Dict("Banana"=>1, "Apple"=>1, "Walnuts"=>1, "Flour"=>1, "Eggs"=>2, "Butter"=>1)
Η εφαρμογή χρειάζεται να στέλνει το καλάθι ενός χρήστη στο κατάστημα για εκτέλεση της παραγγελίας. Ωστόσο, όσοι συλλέγουν τα προϊόντα στο κατάστημα πρέπει να ξέρουν πού βρίσκεται το κάθε προϊόν, μέσω ενός μοναδικού κωδικού διαδρόμου. Το "καλάθι εκτέλεσης παραγγελίας" πρέπει να είναι ταξινομημένο με βάση τους κωδικούς διαδρόμου των προϊόντων, ώστε να βοηθά όσους συλλέγουν τα προϊόντα να είναι πιο αποδοτικοί.
Δημιούργησε τη συνάρτηση send_to_store(<cart>, <aislecodes>), που παίρνει το καλάθι αγορών ενός χρήστη και ένα λεξικό με τους αριθμούς διαδρόμου του καταστήματος.
Η συνάρτηση πρέπει να επιστρέφει ένα συνδυασμένο "καλάθι εκτέλεσης παραγγελίας" που περιέχει ένα ζεύγος aislecode => quantity για κάθε προϊόν που παραγγέλνει ο πελάτης.
Τα προϊόντα πρέπει να εμφανίζονται με τη σειρά των κωδικών διαδρόμου τους.
julia> cart = Dict("Orange" => 1, "Milk" => 2, "Banana" => 3, "Apple" => 2, "Chocolate" => 2);
julia> aislecodes = Dict("Orange" => 2.4, "Milk" => 3.3, "Banana" => 2.6, "Apple" => 2.2, "Chocolate" => 5.7);
julia> send_to_store(cart, aislecodes)
5-element Vector{Pair{Float64, Int64}}:
2.2 => 2
2.4 => 1
2.6 => 3
3.3 => 2
5.7 => 2
Η εφαρμογή δεν μπορεί απλώς να καταχωρεί παραγγελίες πελατών χωρίς τέλος. Κάποια στιγμή, το κατάστημα θα ξεμείνει από διάφορα προϊόντα. Έτσι, το MVP της εφαρμογής σου πρέπει να ενημερώνει το απόθεμα του καταστήματος κάθε φορά που ένας χρήστης στέλνει την παραγγελία του στο κατάστημα. Διαφορετικά, οι πελάτες θα παραγγέλνουν προϊόντα που δεν είναι στην πραγματικότητα διαθέσιμα.
Δημιούργησε τη συνάρτηση update_store_inventory!(<inventory>, <cart>), που παίρνει ένα cart και ένα inventory.
Η συνάρτηση πρέπει να μειώνει τις ποσότητες του αποθέματος του καταστήματος κατά τον αριθμό που "παραγγέλθηκε" στο "cart" και μετά να επιστρέφει ένα λεξικό με όσα προϊόντα έχουν εξαντληθεί (δηλαδή έχουν φτάσει στο 0).
julia> inventory = Dict("Banana" => 15, "Apple" => 12, "Orange" => 1, "Milk" => 4);
julia> cart = Dict("Orange" => 1, "Milk" => 2, "Banana" => 3, "Apple" => 2);
julia> update_store_inventory!(inventory, cart)
Dict{String, Int64} with 1 entry:
"Orange" => 0
julia> inventory
Dict{String, Int64} with 4 entries:
"Milk" => 2
"Apple" => 10
"Orange" => 0
"Banana" => 12
Πέρα από την ενημέρωση του αποθέματος, η εφαρμογή σου μπορεί να βοηθήσει και στην αναπλήρωσή του. Το MVP σου πρέπει να μπορεί να ετοιμάζει μια μίνι παραγγελία με όσα προϊόντα έχουν εξαντληθεί μετά την παραγγελία ενός πελάτη. Αυτό θα κάνει πιο απλή την ενεργοποίηση μιας μεγάλης παραγγελίας. Επιπλέον, μερικές φορές υπάρχουν προϊόντα προσφοράς περιορισμένου χρόνου που δεν βρίσκονται στη λίστα αποθέματος. Αν αυτά εξαντληθούν πριν τελειώσει η περίοδος προσφοράς, σημαίνει ότι ήταν δημοφιλή και μπορούν να προστεθούν στη λίστα αποθέματος.
Δημιούργησε τη συνάρτηση reorder!(<outofstock>, <stock>), που παίρνει outofstock και stock.
Το λεξικό stock περιέχει τα συνήθη είδη αποθέματος και τις ποσότητες αναπαραγγελίας τους.
Το λεξικό outofstock είναι το αποτέλεσμα της update_store_inventory!, δηλαδή ένα λεξικό με προϊόντα μηδενικής ποσότητας.
Οι ποσότητες του outofstock πρέπει να ενημερωθούν ώστε να αντικατοπτρίζουν αυτές του stock και να επιστραφούν.
Επίσης, όσα προϊόντα υπάρχουν στο outofstock αλλά όχι στο stock πρέπει να προστεθούν στο stock με προεπιλεγμένη ποσότητα 100.
julia> inventory = Dict("Banana" => 15, "Apple" => 12, "Orange" => 1, "Milk" => 4, "Chocolate" => 2);
julia> cart = Dict("Orange" => 1, "Milk" => 2, "Banana" => 3, "Apple" => 2, "Chocolate" => 2);
julia> stock = Dict("Banana" => 150, "Apple" => 120, "Orange" => 120, "Milk" => 45);
julia> outofstock = update_store_inventory!(inventory, cart)
Dict{String, Int64} with 1 entry:
"Orange" => 0
"Chocolate" => 0
julia> reorder!(outofstock, stock)
Dict{String, Int64} with 1 entry:
"Orange" => 120
"Chocolate" => 100
julia> stock
Dict{String, Int64} with 5 entries:
"Milk" => 45
"Apple" => 120
"Chocolate" => 100
"Orange" => 120
"Banana" => 150
Γράψου στο Exercism για να μάθεις και να κατακτήσεις Julia με 35 έννοιες128 ασκήσεις και πραγματική καθοδήγηση από ανθρώπους, όλα δωρεάν.