Διαδρομές
/
Swift
Swift
/
Ασκήσεις
/
Πίνακας υψηλών βαθμολογιών
Πίνακας υψηλών βαθμολογιών

Πίνακας υψηλών βαθμολογιών

Άσκηση εκμάθησης

Εισαγωγή

Τα λεξικά είναι ένας από τους βασικούς τύπους συλλογών της Swift. Ένα λεξικό αποθηκεύει μη διατεταγμένες αντιστοιχίσεις μεταξύ μοναδικών κλειδιών και των αντίστοιχων τιμών τους. Όλα τα κλειδιά σε ένα λεξικό πρέπει να είναι του ίδιου τύπου, και όλες οι τιμές πρέπει επίσης να μοιράζονται τον ίδιο τύπο.

Τα literal των λεξικών γράφονται ως ζεύγη key: value χωρισμένα με κόμματα, μέσα σε αγκύλες:

var addresses: Dictionary<String, String> = [
    "The Munsters": "1313 Mockingbird Lane",
    "The Simpsons": "742 Evergreen Terrace",
    "Buffy Summers": "1630 Revello Drive"
]

var sequences: [String: [Int]] = [
    "Euler's totient": [1, 1, 2, 2, 4, 2, 6, 4],
    "Lazy caterer": [1, 2, 4, 7, 11, 16, 22, 29, 37],
    "Carmichael": [561, 1105, 1729, 2465, 2821, 6601, 8911, 10585, 15841]
]

let constants = [
    "pi": 3.14159,
    "e": 2.71828,
    "phi": 1.618033,
    "avogadro": 6.02214076e23
]

Οι τύποι λεξικών μπορούν να γραφτούν ρητά με δύο τρόπους: Dictionary<Key, Value> ή με τη συντομευμένη σύνταξη [Key: Value].

Για να δημιουργήσεις ένα κενό λεξικό, δήλωσε ρητά τους τύπους των κλειδιών και των τιμών του:

var emptyDict1: [Int: Int] = [:]
var emptyDict2 = [Character: String]()
var emptyDict3 = Dictionary<Int, Double>()

Πρόσβαση σε τιμές

Μπορείς να προσπελάσεις τιμές χρησιμοποιώντας τον συμβολισμό με αγκύλες: βάλε το κλειδί μέσα σε αγκύλες μετά το όνομα του λεξικού. Επειδή ένα κλειδί μπορεί να μην υπάρχει στο λεξικό, η πρόσβαση με αγκύλες επιστρέφει έναν προαιρετικό τύπο (Value?). Αν το κλειδί υπάρχει, η Swift επιστρέφει την τιμή που περικλείεται· αν όχι, επιστρέφει nil:

let munster: String? = addresses["The Munsters"]
// Returns Optional("1313 Mockingbird Lane")

let carmichael = sequences["Carmichael"]
// Returns Optional([561, 1105, 1729, 2465, 2821, 6601, 8911, 10585, 15841])

let planck = constants["planck"]
// Returns nil

Για να αποφύγεις να δουλεύεις με προαιρετικούς τύπους, μπορείς να δώσεις μια προεπιλεγμένη τιμή χρησιμοποιώντας την παράμετρο default:

let e: Double = constants["e", default: 0]
// Returns 2.71828

let hoagie: [Int] = sequences["Hoagie", default: []]
// Returns []

let betty = addresses["Betty Cooper", default: "Address unknown"]
// Returns "Address unknown"

Τροποποίηση λεξικών

Για μεταβλητά λεξικά που δηλώνονται με var, μπορείς να προσθέσεις ή να ενημερώσεις ζεύγη κλειδιού-τιμής χρησιμοποιώντας ανάθεση με αγκύλες:

sequences["Euler's totient"]?.append(contentsOf: [6, 4])
// sequences["Euler's totient"] is now [1, 1, 2, 2, 4, 2, 6, 4, 6, 4]

addresses["Betty Cooper"] = "111 Queens Ave."
addresses["Betty Cooper", default: "Address unknown"]
// Returns "111 Queens Ave."

constants["Gelfond's"] = 23.140692
// Compiler error: Cannot assign through subscript: 'constants' is a 'let' constant

Διάσχιση ενός λεξικού

Μπορείς να διατρέξεις κάθε ζεύγος κλειδιού-τιμής ενός λεξικού χρησιμοποιώντας έναν βρόχο for-in. Κάθε στοιχείο παρέχεται ως πλειάδα (key, value):

for (name, address) in addresses {
    print("\(name) lives at \(address)")
}

Ταξινόμηση λεξικών

Επειδή τα λεξικά δεν έχουν σειρά, η ταξινόμησή τους παράγει έναν πίνακα από ζεύγη κλειδιού-τιμής. Μπορείς να περάσεις ένα closure στη μέθοδο sorted(by:) που συγκρίνει δύο πλειάδες (key, value) και επιστρέφει true αν η πρώτη πλειάδα πρέπει να εμφανιστεί πριν από τη δεύτερη:

func sortByNameLengthThenValue(_ lhs: (key: String, value: Double), _ rhs: (key: String, value: Double)) -> Bool {
    let left = lhs.value + Double(lhs.key.count)
    let right = rhs.value + Double(rhs.key.count)
    return left < right
}

let sortedConstants = constants.sorted(by: sortByNameLengthThenValue)

Οδηγίες

Σε αυτή την άσκηση, υλοποιείς έναν τρόπο για να παρακολουθείς τις υψηλές βαθμολογίες του πιο δημοφιλούς παιχνιδιού στην τοπική αίθουσα με ηλεκτρονικά παιχνίδια.

Έχεις 7 συναρτήσεις να υλοποιήσεις, όλες σχετικές με την επιστροφή και τον χειρισμό ενός λεξικού με δεδομένα υψηλών βαθμολογιών.

1. Ορισμός νέου λεξικού υψηλών βαθμολογιών

Δημιούργησε μια συνάρτηση newScoreBoard() που δεν παίρνει παραμέτρους και επιστρέφει ένα νέο λεξικό υψηλών βαθμολογιών, το οποίο χρησιμοποιεί τιμές τύπου String για τα κλειδιά και τιμές τύπου Int για τις τιμές.

2. Προσθήκη παικτών στο λεξικό υψηλών βαθμολογιών

Για να προσθέσεις έναν παίκτη στο λεξικό υψηλών βαθμολογιών, όρισε τη συνάρτηση addPlayer(_:_:_:), η οποία παίρνει 3 παραμέτρους:

  • Η πρώτη παράμετρος είναι το λεξικό με τις βαθμολογίες. Θα πρέπει να είναι παράμετρος in-out.
  • Η δεύτερη παράμετρος είναι το όνομα του παίκτη ως συμβολοσειρά.
  • Η τρίτη παράμετρος είναι η βαθμολογία ως ακέραιος. Η παράμετρος είναι προαιρετική, υλοποίησε την τρίτη παράμετρο με προεπιλεγμένη τιμή 0.
var highScores = newScoreBoard()
addPlayer(&highScores, "Dave Thomas")
// Returns ["Dave Thomas": 0]
addPlayer(&highScores, "José Valim", 486_373)
// Returns ["Dave Thomas": 0, "José Valim": 486_373]

3. Αφαίρεση παικτών από το λεξικό βαθμολογιών

Για να αφαιρέσεις έναν παίκτη από το λεξικό υψηλών βαθμολογιών, όρισε τη συνάρτηση removePlayer(_:_:), η οποία παίρνει 2 παραμέτρους:

  • Η πρώτη παράμετρος είναι το λεξικό με τις βαθμολογίες. Θα πρέπει να είναι παράμετρος in-out.
  • Η δεύτερη παράμετρος είναι το όνομα του παίκτη ως συμβολοσειρά.

Αυτή η συνάρτηση θα πρέπει να αφαιρεί τον παίκτη από το λεξικό αν βρίσκεται σε αυτό και να μην κάνει τίποτα σε αντίθετη περίπτωση.

var highScores = ["Dave Thomas": 0, "José Valim": 486_373]
removePlayer(&highScores, "Dave Thomas")
// Returns ["José Valim": 486_373]
removePlayer(&highScores, "Rose Fanaras")
// Returns ["José Valim": 486_373]

4. Επαναφορά της βαθμολογίας ενός παίκτη

Για να κάνεις επαναφορά στη βαθμολογία ενός παίκτη, όρισε τη συνάρτηση resetPlayer(_:_:), η οποία παίρνει 2 παραμέτρους:

  • Η πρώτη παράμετρος είναι το λεξικό με τις βαθμολογίες. Θα πρέπει να είναι παράμετρος in-out.
  • Η δεύτερη παράμετρος είναι το όνομα του παίκτη ως συμβολοσειρά, του οποίου τη βαθμολογία θέλεις να επαναφέρεις.

Η συνάρτηση θα θέσει τη βαθμολογία του παίκτη σε 0. Αν ο παίκτης δεν βρίσκεται στο λεξικό, τότε δεν θα πρέπει να συμβεί τίποτα.

var highScores = ["Dave Thomas": 486_373, "José Valim": 10]
resetScore(&highScores, "Dave Thomas")
// Returns ["Dave Thomas": 0, "José Valim": 10]

5. Ενημέρωση της βαθμολογίας ενός παίκτη

Για να ενημερώσεις τη βαθμολογία ενός παίκτη προσθέτοντας στην προηγούμενη βαθμολογία, όρισε τη συνάρτηση updateScore, η οποία παίρνει 3 παραμέτρους:

  • Η πρώτη παράμετρος είναι το λεξικό με τις βαθμολογίες. Θα πρέπει να είναι παράμετρος in-out.
  • Η δεύτερη παράμετρος είναι το όνομα του παίκτη ως συμβολοσειρά, του οποίου τη βαθμολογία θέλεις να ενημερώσεις.
  • Η τρίτη παράμετρος είναι η βαθμολογία που θέλεις να προσθέσεις στην αποθηκευμένη υψηλή βαθμολογία.
var highScores = ["Dave Thomas": 0, "José Valim": 486_373]
addPlayer(&highScores, "Freyja Ćirić", 12_771_008)
updateScore(&highScores, "Freyja Ćirić", 73)
// Returns ["Dave Thomas": 0, "José Valim": 486_373, "Freyja Ćirić": 12_771_081]

6. Λήψη λίστας παικτών με βαθμολογίες ταξινομημένες κατά όνομα παίκτη

Όρισε τη συνάρτηση orderByPlayers, η οποία παίρνει 1 παράμετρο:

  • Η πρώτη παράμετρος είναι το λεξικό με τις βαθμολογίες.

Η συνάρτηση θα επιστρέφει έναν πίνακα από πλειάδες (String, Int) που είναι οι παίκτες και οι υψηλές βαθμολογίες τους, ταξινομημένες σε αύξουσα σειρά κατά το όνομα του παίκτη.

var highScores = ["Dave Thomas": 0, "José Valim": 486_373, "Freyja Ćirić": 12_771_091]
orderByPlayers(highScores)
// Returns [("Dave Thomas", 0), ("Freyja Ćirić", 12_771_091), ("José Valim", 486_373)]

7. Λήψη λίστας παικτών σε φθίνουσα σειρά κατά βαθμολογία

Για να πάρεις μια λίστα παικτών ταξινομημένη κατά βαθμολογία σε φθίνουσα σειρά, όρισε τη συνάρτηση orderByScores, η οποία παίρνει 1 παράμετρο:

  • Η πρώτη παράμετρος είναι το λεξικό με τις βαθμολογίες.

Η συνάρτηση θα επιστρέφει έναν πίνακα από πλειάδες (String, Int) που είναι οι παίκτες και οι υψηλές βαθμολογίες τους, ταξινομημένες σε φθίνουσα σειρά κατά τη βαθμολογία του παίκτη.

var highScores = ["Dave Thomas": 0, "José Valim": 486_373, "Freyja Ćirić": 12_771_091]
orderByScores(highScores)
// Returns [("Freyja Ćirić", 12_771_091), ("José Valim", 486_373), ("Dave Thomas", 0)]
Επεξεργασία μέσω GitHub Ο σύνδεσμος ανοίγει σε νέο παράθυρο ή καρτέλα
Swift Exercism

Έτοιμος να ξεκινήσεις την άσκηση Πίνακας υψηλών βαθμολογιών;

Γράψου στο Exercism για να μάθεις και να κατακτήσεις Swift με 35 έννοιες116 ασκήσεις και πραγματική καθοδήγηση από ανθρώπους, όλα δωρεάν.