مسیرها
/
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)

دستورالعمل‌ها

در این تمرین، روشی را پیاده‌سازی می‌کنید که امتیازهای بالای محبوب‌ترین بازی در سالن بازی‌های آرکید محله‌تان را ثبت کند.

شما باید ۷ تابع پیاده‌سازی کنید که همه به برگرداندن و دستکاری یک «دیکشنری» از داده‌های امتیازهای بالا مربوط می‌شوند.

1. یک دیکشنری جدید امتیاز بالا تعریف کنید

تابعی به نام newScoreBoard() ایجاد کنید که هیچ پارامتری نمی‌گیرد و یک دیکشنری جدید امتیاز بالا برمی‌گرداند که برای کلیدها از مقادیری از نوع String و به عنوان مقدارها از مقادیری از نوع Int استفاده می‌کند.

2. بازیکن‌ها را به دیکشنری امتیاز بالا اضافه کنید

برای افزودن بازیکن به دیکشنری امتیاز بالا، تابع addPlayer(_:_:_:) را تعریف کنید. این تابع ۳ پارامتر می‌گیرد:

  • پارامتر اول دیکشنری امتیازها است. این باید یک پارامتر ورودی-خروجی باشد.
  • پارامتر دوم اسم بازیکن به صورت یک رشته است.
  • پارامتر سوم امتیاز به صورت یک عدد صحیح است. این پارامتر اختیاری است؛ آن را با مقدار پیش‌فرض ۰ پیاده‌سازی کنید.
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(_:_:) را تعریف کنید. این تابع ۲ پارامتر می‌گیرد:

  • پارامتر اول دیکشنری امتیازها است. این باید یک پارامتر ورودی-خروجی باشد.
  • پارامتر دوم اسم بازیکن به صورت یک رشته است.

این تابع باید بازیکن را، در صورتی که در دیکشنری باشد، از آن حذف کند و در غیر این صورت کاری انجام ندهد.

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(_:_:) را تعریف کنید. این تابع ۲ پارامتر می‌گیرد:

  • پارامتر اول دیکشنری امتیازها است. این باید یک پارامتر ورودی-خروجی باشد.
  • پارامتر دوم اسم بازیکن به صورت یک رشته است که می‌خواهید امتیازش را بازنشانی کنید.

این تابع امتیاز بازیکن را روی ۰ تنظیم می‌کند. اگر بازیکن در دیکشنری نباشد، نباید اتفاقی بیفتد.

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

5. امتیاز یک بازیکن را به‌روزرسانی کنید

برای به‌روزرسانی امتیاز یک بازیکن با افزودن به امتیاز قبلی، updateScore را تعریف کنید. این تابع ۳ پارامتر می‌گیرد:

  • پارامتر اول دیکشنری امتیازها است. این باید یک پارامتر ورودی-خروجی باشد.
  • پارامتر دوم اسم بازیکن به صورت یک رشته است که می‌خواهید امتیازش را به‌روزرسانی کنید.
  • پارامتر سوم امتیازی است که می‌خواهید به امتیاز بالای ذخیره‌شده اضافه کنید.
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 را تعریف کنید که ۱ پارامتر می‌گیرد:

  • پارامتر اول دیکشنری امتیازها است.

این تابع یک آرایه از تاپل‌های (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 را تعریف کنید که ۱ پارامتر می‌گیرد:

  • پارامتر اول دیکشنری امتیازها است.

این تابع یک آرایه از تاپل‌های (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 تمرین و مربی‌گری انسانی واقعی یاد بگیرید و در آن استاد شوید، همه‌ی این‌ها رایگان.