القواميس هي أحد أنواع المجموعات الأساسية في 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 دوال، جميعها تتعلق بإرجاع قاموس من بيانات أعلى الدرجات والتعامل معه.
أنشئ دالة newScoreBoard() لا تأخذ أي معاملات وتُرجع قاموس أعلى درجات جديد يستخدم قيمًا من النوع String للمفاتيح وقيمًا من النوع Int للقيم.
لإضافة لاعب إلى قاموس أعلى الدرجات، عرّف addPlayer(_:_:_:)، وهي دالة تأخذ 3 معاملات:
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]
لإزالة لاعب من قاموس أعلى الدرجات، عرّف 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]
لإعادة ضبط درجة لاعب، عرّف resetPlayer(_:_:)، وهي تأخذ معاملين:
ستجعل الدالة درجة اللاعب مساوية لـ 0. إذا لم يكن اللاعب موجودًا في القاموس، فلا ينبغي أن يحدث أي شيء.
var highScores = ["Dave Thomas": 486_373, "José Valim": 10]
resetScore(&highScores, "Dave Thomas")
// Returns ["Dave Thomas": 0, "José Valim": 10]
لتحديث درجة لاعب بإضافتها إلى الدرجة السابقة، عرّف updateScore، وهي تأخذ 3 معاملات:
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]
عرّف الدالة 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)]
للحصول على قائمة من اللاعبين مرتبة حسب الدرجات بترتيب تنازلي، عرّف 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)]
سجّل في Exercism لتتعلّم وتتقن Swift عبر 35 مفهومًا116 تمرينًا، وإرشاد بشري حقيقي، وكل ذلك مجانًا.