Ένα αντικείμενο JSON είναι, για να δανειστούμε ορολογία από άλλες γλώσσες, ένα "hash", ένα "map" ή ένα "dictionary".
Η JSON ορίζει ένα αντικείμενο ως εξής:
Ένα αντικείμενο είναι ένα σύνολο από ζεύγη όνομα/τιμή χωρίς συγκεκριμένη σειρά. Ένα αντικείμενο αρχίζει με
{αριστερό άγκιστρο και τελειώνει με}δεξί άγκιστρο. Κάθε όνομα ακολουθείται από:άνω και κάτω τελεία και τα ζεύγη όνομα/τιμή χωρίζονται από,κόμμα.
Το όνομα πρέπει να είναι συμβολοσειρά. Μια άλλη λέξη για το όνομα είναι κλειδί.
Η τιμή μπορεί να είναι οποιουδήποτε τύπου JSON. Διαφορετικές τιμές στο ίδιο αντικείμενο μπορούν να είναι διαφορετικών τύπων, όπως σε αυτό το παράδειγμα.
{
"name": "Jane",
"age": 42,
"pets": ["cat", "fish"],
"address": {"street": "123 Main St", "city": "Springfield"}
}
Σημείωσε ότι δεν πρέπει να υπάρχει κόμμα μετά το τελευταίο ζεύγος κλειδιού-τιμής.
Χρησιμοποίησε άγκιστρα για να συγκεντρώσεις τα ζεύγη ονόματος/τιμής. Παρόλο που τα ονόματα πρέπει να είναι συμβολοσειρές, δεν χρειάζεται να μπουν σε εισαγωγικά αν έχουν μορφή αναγνωριστικού (αποτελούνται από αλφαριθμητικούς χαρακτήρες και κάτω παύλα και δεν ξεκινούν με ψηφίο).
{name: "Jane", age: 42}
Είναι έγκυρο να χρησιμοποιήσεις κλειδιά που δεν έχουν μορφή αναγνωριστικού. Απλώς βάλε τα σε εισαγωγικά.
{"first name": "Jane", "last name": "Lopez", age: 42}
Αν το όνομα είναι το αποτέλεσμα μιας έκφρασης, η έκφραση πρέπει να είναι μέσα σε παρενθέσεις.
$ echo "Jane" | jq -Rc '{.: 42}'
# verbose error message ...
$ echo "Jane" | jq -Rc '{(.): 42}'
{"Jane":42}
Οι τιμές ανακτώνται από ένα αντικείμενο με συμβολισμό τελείας.
{name: "Jane", age: 42} | .age # => 42
Αν δεν μπορείς να αναφερθείς στο κλειδί ως αναγνωριστικό, χρησιμοποίησε συμβολισμό με αγκύλες.
"name" as $key | {name: "Jane", age: 42} | .$key # => error
"name" as $key | {name: "Jane", age: 42} | .[$key] # => "Jane"
Για να προσθέσεις ένα νέο ζεύγος κλειδιού-τιμής σε έναν πίνακα ή να ενημερώσεις την τιμή ενός υπάρχοντος κλειδιού, χρησιμοποίησε τον τελεστή ανάθεσης =, με μια έκφραση θέσης στην αριστερή πλευρά.
{name: "Jane", age: 42} | .sport = "tennis" | .age = 21
# => {
# "name": "Jane",
# "age": 21,
# "sport": "tennis"
# }
Ο τελεστής + θα συγχωνεύσει τα αντικείμενα.
{Richard: 54} + {Jane: 42}
# => {
# "Richard": 54,
# "Jane": 42
# }
Χρησιμοποίησε τη συνάρτηση del για να αφαιρέσεις ένα κλειδί.
Επιστρέφει το ενημερωμένο αντικείμενο.
{name: "Jane", age: 42} | del(.age) # => {"name": "Jane"}
Η παράμετρος της del είναι μια έκφραση θέσης (με συμβολισμό τελείας ή αγκυλών) που αντιστοιχεί σε ένα κλειδί του αντικειμένου.
Η jq την ονομάζει έκφραση διαδρομής.
Δεν αρκεί να δώσεις απλώς μια συμβολοσειρά.
{name: "Jane", age: 42} | del(name) # error: name/0 is not defined
{name: "Jane", age: 42} | del("name") # error: Invalid path expression with result "name"
{name: "Jane", age: 42} | del(.name) # OK
{name: "Jane", age: 42} | del(.["name"]) # OK
Για να ελέγξεις αν το αντικείμενο έχει ένα κλειδί, χρησιμοποίησε τη συνάρτηση has.
{name: "Jane", age: 42} as $example
|
($example | has("name")), # => true
($example | has("sport")) # => false
Έλεγξε αν ένα κλειδί βρίσκεται σε ένα αντικείμενο με το in.
{name: "Jane", age: 42} as $example
|
("name" | in($example)), # => true
("sport" | in($example)) # => false
Χρησιμοποίησε τη συνάρτηση keys για να εμφανίσεις μια λίστα με όλα τα κλειδιά.
{name: "Jane", age: 42} | keys # => ["age", "name"]
Σημείωσε ότι η keys θα ταξινομήσει τα κλειδιά.
Για να πάρεις τα κλειδιά με την αρχική τους σειρά, χρησιμοποίησε τη keys_unsorted.
Δεν υπάρχει αντίστοιχη συνάρτηση για να εμφανίσεις όλες τις τιμές.
Ωστόσο, το φίλτρο .[] εμφανίζει τις τιμές του αντικειμένου ως ροή, και αυτή η ροή μπορεί να συλλεχθεί με τον κατασκευαστή πίνακα [...].
[{first: "Jane", last: "Lopez", status: "awesome!"} | .[]]
# => ["Jane", "Lopez", "awesome!"]
Η συνάρτηση map_values(filter) εφαρμόζει το φίλτρο σε κάθε τιμή του αντικειμένου.
{first: "Jane", last: "Lopez", status: "awesome!"}
| map_values(ascii_upcase)
# => {"first": "JANE", "last": "LOPEZ", "status": "AWESOME!"}
Για να επαναλάβεις πάνω σε ένα αντικείμενο, πρέπει πρώτα να το μετατρέψεις σε πίνακα από αντικείμενα κλειδιού-τιμής.
Η συνάρτηση to_entries το κάνει αυτό.
{name: "Jane", age: 42} | to_entries'
# => [
# {
# "key": "name",
# "value": "Jane"
# },
# {
# "key": "age",
# "value": 42
# }
# ]
Σε αυτό το σημείο, μπορείς να χρησιμοποιήσεις συναρτήσεις επανάληψης πινάκων, όπως τη map.
Η συνάρτηση from_entries κάνει το αντίστροφο: μετατρέπει έναν πίνακα από αντικείμενα κλειδιού-τιμής σε αντικείμενο.
[
{"key":"name", "value":"Jane"},
{"key":"age", "value":42}
] | from_entries # =>{"name": "Jane", "age": 42}
Για να εφαρμόσεις ένα φίλτρο σε κάθε ζεύγος κλειδιού-τιμής ενός αντικειμένου, χρησιμοποίησε τη συνάρτηση with_entries(filter).
Για παράδειγμα, με δεδομένο ένα αντικείμενο που αντιστοιχίζει ένα όνομα σε μια ηλικία, τα κλειδιά και οι τιμές μπορούν να αντιστραφούν ως εξής.
{"Jane": 42, "Richard": 54}
| with_entries({key: (.value | tostring), value: .key})
εμφανίζει
{
"42": "Jane",
"54": "Richard"
}
Η with_entries(filter) είναι το ίδιο με
to_entries | map(filter) | from_entries
Σε αυτή την άσκηση, υλοποιείς έναν τρόπο για να παρακολουθείς τα υψηλά σκορ για το πιο δημοφιλές παιχνίδι στην τοπική αίθουσα παιχνιδιών σου.
Έχεις 6 συναρτήσεις να υλοποιήσεις, που σχετίζονται κυρίως με τον χειρισμό ενός αντικειμένου που περιέχει τα υψηλά σκορ.
Γράψε μια συνάρτηση create_score_board που δημιουργεί ένα αντικείμενο το οποίο χρησιμεύει ως πίνακας υψηλών σκορ.
Τα κλειδιά αυτού του αντικειμένου θα είναι τα ονόματα των παικτών, ενώ οι τιμές θα είναι τα σκορ τους.
Για σκοπούς δοκιμών, θέλεις να συμπεριλάβεις απευθείας μία καταχώριση στο αντικείμενο.
Αυτή η αρχική καταχώριση θα πρέπει να αποτελείται από το "The Best Ever" ως όνομα παίκτη και το 1000000 ως σκορ.
create_score_board
# returns an object with one initial entry
Για να προσθέσεις έναν παίκτη στον πίνακα υψηλών σκορ, υλοποίησε τη συνάρτηση add_player.
Δέχεται έναν πίνακα υψηλών σκορ ως είσοδο και χρειάζεται δύο παραμέτρους: το όνομα του παίκτη και το σκορ του παίκτη.
Η συνάρτηση επιστρέφει το αντικείμενο του πίνακα υψηλών σκορ με τον νέο παίκτη προσθεμένο.
{"José Valim", 486373}
| add_player("Dave Thomas"; 0)
# => {"Dave Thomas": 0, "José Valim": 486373} -- in some order
Αν ο παίκτης βρίσκεται ήδη στον πίνακα, επέστρεψε τον πίνακα όπως είναι.
Αν οι παίκτες παραβούν τους κανόνες της αίθουσας παιχνιδιών, αφαιρούνται χειροκίνητα από τον πίνακα υψηλών σκορ.
Υλοποίησε τη συνάρτηση remove_player, η οποία δέχεται έναν πίνακα ως είσοδο και μία παράμετρο, το όνομα του παίκτη που θα αφαιρεθεί.
Αυτή η συνάρτηση θα πρέπει να αφαιρεί την καταχώριση του συγκεκριμένου παίκτη από τον πίνακα και να επιστρέφει τον νέο πίνακα.
Αν ο παίκτης δεν βρισκόταν εξαρχής στον πίνακα, δεν θα πρέπει να συμβεί τίποτα στον πίνακα, και θα πρέπει να επιστραφεί όπως είναι.
{"Dave Thomas": 0} | remove_player("Dave Thomas")
# => {}
{"Dave Thomas": 0} | remove_player("Rose Fanaras")
# => {"Dave Thomas": 0}
Αν ένας παίκτης ολοκληρώσει άλλο ένα παιχνίδι στην αίθουσα παιχνιδιών, ένα συγκεκριμένο ποσό πόντων θα προστεθεί στο προηγούμενο σκορ του πίνακα.
Υλοποίησε τη συνάρτηση update_score, η οποία δέχεται έναν πίνακα υψηλών σκορ ως είσοδο και χρειάζεται δύο παραμέτρους: το όνομα του παίκτη και το ποσό του σκορ που θα προστεθεί.
Η συνάρτηση θα πρέπει να επιστρέφει τον πίνακα υψηλών σκορ αφού γίνει η ενημέρωση.
{"Freyja Ćirić": 12771000} | update_score("Freyja Ćirić"; 73)
# => {"Freyja Ćirić": 12771073}
Αυτή η συνάρτηση θα πρέπει να προσθέτει τον παίκτη στον πίνακα αν δεν βρισκόταν ήδη σε αυτόν.
Η αίθουσα παιχνιδιών κρατά έναν ξεχωριστό πίνακα υψηλών σκορ τις Δευτέρες. Στο τέλος της ημέρας, κάθε παίκτης σε αυτόν τον πίνακα παίρνει 100 επιπλέον πόντους.
Υλοποίησε τη συνάρτηση apply_monday_bonus.
Η συνάρτηση προσθέτει τους πόντους μπόνους για κάθε παίκτη που είναι καταγεγραμμένος σε αυτόν τον πίνακα.
{
"Dave Thomas": 44,
"Freyja Ćirić": 539,
"José Valim": 265
}
| apply_monday_bonus
# => {"Dave Thomas": 144, "Freyja Ćirić": 639, "José Valim": 365}
Διαφορετικές αίθουσες παιχνιδιών συναγωνίζονται μεταξύ τους για να καθορίσουν ποια έχει τους καλύτερους παίκτες. Η αίθουσα με το υψηλότερο συνολικό σκορ κερδίζει τη δόξα.
Γράψε μια συνάρτηση total_score.
Δέχεται έναν πίνακα υψηλών σκορ ως είσοδο και επιστρέφει το άθροισμα των σκορ όλων των παικτών.
{
"Dave Thomas": 44,
"Freyja Ćirić": 539,
"José Valim": 265
}
| total_score
# => 848
Γράψου στο Exercism για να μάθεις και να κατακτήσεις jq με 12 έννοιες75 ασκήσεις και πραγματική καθοδήγηση από ανθρώπους, όλα δωρεάν.