Menu
Coddy logo textTech
flag Ar iconالعربيةdown icon

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)          // بالضبط الخصائص التي يقارنها ==
}
challenge icon

التحدي

سهل

يتحرك روبوت على شبكة باستخدام 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) }
quiz iconاختبر نفسك

يتضمن هذا الدرس اختبارًا قصيرًا. ابدأ الدرس للإجابة عليه وتتبّع تقدمك.

جميع دروس البرمجة كائنية التوجه

تدرّب بنفسك: Playground لـ Swift