Треки
/
Swift
Swift
/
Вправи
/
Табло рекордів
Табло рекордів

Табло рекордів

Навчальна вправа

Вступ

Словники належать до основних типів колекцій у Swift. Словник зберігає невпорядковані відповідності між унікальними ключами та відповідними значеннями. Усі ключі в словнику мають бути одного типу, і всі значення так само.

Літерали словників записують як розділені комами пари 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)")
}

Сортування словників

Оскільки словники невпорядковані, їхнє сортування дає масив пар ключ-значення. У метод 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-параметр.
  • Другий параметр - імʼя гравця у вигляді рядка тексту (англ. string).
  • Третій параметр - результат у вигляді цілого числа. Параметр необовʼязковий. Реалізуйте третій параметр із типовим значенням 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 вправ та справжнє наставництво від людей, і все це безкоштовно.