Hashable
جزء من قسم البرمجة كائنية التوجه في رحلة Swift على Coddy. الدرس 40 من 57.
Hashable تتيح تخزين القيم في Set أو استخدامها كمفاتيح في Dictionary. الهاش هو رقم يُحسَب من القيمة، ويُستخدم للعثور عليها بسرعة. تحصل البُنى والتعدادات التي تكون جميع خصائصها من النوع Hashable على ذلك من خلال التصريح بالتوافق:
struct Point: Hashable {
let x: Int, y: Int
}
var visited: Set<Point> = []
visited.insert(Point(x: 0, y: 0))
visited.insert(Point(x: 1, y: 0))
visited.insert(Point(x: 0, y: 0))
print(visited.count)
print(visited.contains(Point(x: 1, y: 0)))الناتج:
2
trueالقيم القابلة للتجزئة تُعد مفاتيح جيدة للقواميس، على سبيل المثال لعدّ تكرارات القيم المُنظَّمة:
struct Pair: Hashable {
let from: String, to: String
}
let trips = [Pair(from: "A", to: "B"), Pair(from: "B", to: "C"), Pair(from: "A", to: "B")]
var counts: [Pair: Int] = [:]
for t in trips { counts[t, default: 0] += 1 }
print(counts[Pair(from: "A", to: "B")]!)الناتج:
2يبني Hashable على Equatable. عندما يقارن == بعض الخصائص فقط، يجب أن تستخدم التجزئة الخصائص نفسها، ويتم ذلك في hash(into:). وإلا فقد تحصل قيمتان متساويتان على تجزئتين مختلفتين، وستحتفظ مجموعة بهما كلتيهما:
struct User: Hashable {
let id: Int
var name: String
static func == (lhs: User, rhs: User) -> Bool { lhs.id == rhs.id }
func hash(into hasher: inout Hasher) { hasher.combine(id) }
}
let users: Set<User> = [User(id: 1, name: "Ada"), User(id: 1, name: "Ada L."), User(id: 2, name: "Bo")]
print(users.count)الناتج:
2القاعدة التي يجب تذكّرها: القيم المتساوية يجب أن تكون لها تجزئات متساوية. تتغير قيم التجزئة بين عمليات تشغيل البرنامج، لذا لا تخزّنها أو تطبعها أبدًا؛ استخدمها فقط من خلال المجموعات والقواميس.
// قيم متساوية -> تجزئات متساوية (مطلوب)
// قيم مختلفة -> عادةً تجزئات مختلفة
func hash(into hasher: inout Hasher) {
hasher.combine(id) // بالضبط الخصائص التي يقارنها ==
}التحدي
سهليتحرك روبوت على شبكة باستخدام U وD وL وR خطوة واحدة في كل مرة بدءًا من (0, 0). اجعل Position (x, y) من النوع Hashable وأكمل explore(_:)، التي تُرجع ثلاثة أسطر: visited 5 cells (عدد المواضع المميزة بما في ذلك موضع البداية)، وrevisits 2 (التحركات التي انتهت في خلية تمت زيارتها مسبقًا)، وmost visited (0, 0) x3 (الخلية التي تم الدخول إليها أكبر عدد من المرات، مع احتساب البداية كزيارة واحدة؛ وعند التعادل يفوز أول موضع يصل إلى ذلك العدد).
يقرأ الكود المزوَّد سطرًا واحدًا من التحركات ويطبع كل سطر مُعاد.
ضع الكود الخاص بك في Position.swift وFunctions.swift. يحتوي main.swift على كود الإدخال/الإخراج المزوَّد ولا يمكن تعديله.
جرّب بنفسك
// كود الإدخال/الإخراج المُزوَّد: أبقِه كما هو
var input: [String] = []
while let line = readLine() { input.append(line) }
for line in explore(input[0]) { print(line) }
يتضمن هذا الدرس اختبارًا قصيرًا. ابدأ الدرس للإجابة عليه وتتبّع تقدمك.
جميع دروس البرمجة كائنية التوجه
1الأصناف والكائنات
العمل مع الملفاتتعريف الأصنافالأساليب وselfالمُهيِّئاتالأصناف هي مراجعمراجعة - بطاقة المكتبة4التغليف
التحكم في الوصولللقراءة فقط من الخارجحماية الحالةالمهيئات القابلة للفشلمراجعة - الحساب البنكي7تعدد الأشكال والأنواع العامة
تعدد الأشكالتحويل الأنواعالدوال العامةالأنواع العامةمراجعة - حاسبة الأشكالتدرّب بنفسك: Playground لـ Swift