البحث في Dictionary
وصول سريع إلى قيم المفاتيح
البحث في Dictionary درس مجاني في C# Academy على CoddyKit. هذا هو الدرس 2 من أصل 4. يمكنك قراءة الدرس كاملاً أدناه مجاناً — ثم تمرن عليه مباشرة في المتصفح باستخدام محرر أكواد مدمج ومدرس ذكاء اصطناعي متاح 24/7. هذا الدرس جزء من مسار التعلم في C# Academy، وتقدمك يتزامن عبر الويب وتطبيق CoddyKit. تتضمن دورة C# Academy 4 دروس في المجموع.
أزواج المفتاح والقيمة
تربط Dictionary<TKey, TValue> المفاتيح الفريدة بالقيم. فكّر فيها كجدول بحث: مرّر مفتاحًا لتحصل على قيمته بسرعة.
يعتمد هذا النوع على جدول تجزئة، لذلك يكون العثور على قيمة باستخدام مفتاحها بتكلفة O(1) في المتوسط، وهي أسرع بكثير من مسح قائمة.
using System.Collections.Generic;
var ages = new Dictionary<string, int>();
ages["Ann"] = 30;
ages["Bob"] = 25;تهيئة Dictionary
يمكنك تهيئة القاموس مسبقًا باستخدام مهيئ مجموعة. ويربط كل إدخال مفتاحًا بقيمته.
يجب أن تكون المفاتيح فريدة. ويؤدي توفير المفتاح نفسه مرتين في المهيئ إلى طرح ArgumentException في وقت التشغيل.
using System;
using System.Collections.Generic;
class Program {
static void Main() {
var caps = new Dictionary<string, string> {
["FR"] = "Paris",
["JP"] = "Tokyo"
};
Console.WriteLine(caps["JP"]);
}
}القراءة باستخدام المفتاح
استخدم المفهرس للقراءة: dict[key]. وتبلغ كلفتها O(1) في المتوسط.
لكن انتبه: إذا كان المفتاح مفقودًا، فإن المفهرس يرمي KeyNotFoundException. وتُعد قراءة مفتاح غير موجودة واحدةً من أكثر أخطاء القواميس شيوعًا.
var ages = new Dictionary<string, int> { ["Ann"] = 30 };
int a = ages["Ann"]; // 30
// int b = ages["Zoe"]; // throws KeyNotFoundExceptionالبحث الآمن باستخدام TryGetValue
يتجنب TryGetValue الاستثناءات. فهو يعيد true ويضبط متغير out عند وجود المفتاح، أو يعيد false خلاف ذلك.
وهذه هي الطريقة الاصطلاحية الخالية من تخصيصات الذاكرة للبحث عن قيمة لست متأكدًا من وجودها.
using System;
using System.Collections.Generic;
class Program {
static void Main() {
var ages = new Dictionary<string, int> { ["Ann"] = 30 };
if (ages.TryGetValue("Ann", out int v))
Console.WriteLine(v);
}
}ContainsKey والقيم الافتراضية
يتحقق ContainsKey من وجود مفتاح دون قراءة القيمة، وتبلغ كلفته O(1). استخدمه قبل القراءة باستخدام المفهرس عندما تحتاج فقط إلى إجابة بنعم أو لا.
إذا استدعيت كلًا من ContainsKey والمفهرس، فستحسب تجزئة المفتاح مرتين. أما TryGetValue فيحسبها مرة واحدة، ولذلك يكون أسرع عادةً.
var ages = new Dictionary<string, int> { ["Ann"] = 30 };
if (ages.ContainsKey("Ann"))
System.Console.WriteLine(ages["Ann"]);الإضافة مقابل الإسناد
يُدخل المفهرس dict[key] = value زوجًا جديدًا أو يستبدل زوجًا موجودًا. أما Add(key, value) فيُدخل زوجًا جديدًا فقط، ويرمي استثناءً إذا كان المفتاح موجودًا بالفعل.
استخدم Add عندما يجب اعتبار المفتاح المكرر خطأً، واستخدم المفهرس عندما يكون الاستبدال مقبولًا.
using System;
using System.Collections.Generic;
class Program {
static void Main() {
var d = new Dictionary<string, int>();
d["x"] = 1;
d["x"] = 2; // overwrite, fine
Console.WriteLine(d["x"]);
}
}إزالة الإدخالات
تحذف Remove(key) زوجًا وتعيد true إذا كان المفتاح موجودًا، وتبلغ كلفتها O(1) في المتوسط.
يعيد أحد التحميلات الزائدة القيمة المحذوفة عبر معلمة out، وهذا مفيد عندما تريد حذف القيمة واستخدامها في خطوة واحدة.
var d = new Dictionary<string, int> { ["a"] = 1, ["b"] = 2 };
bool removed = d.Remove("a"); // true
bool again = d.Remove("a"); // falseالتكرار على الأزواج
يعيد التكرار عناصر من النوع KeyValuePair<TKey, TValue>. فكّك هذه العناصر إلى مفتاح وقيمة للحصول على تعليمات برمجية واضحة.
ترتيب التعداد غير مضمون؛ فلا تعتمد أبدًا على ترتيب إدراج الإدخالات. استخدم Keys أو Values للتكرار على أحد الجانبين فقط.
using System;
using System.Collections.Generic;
class Program {
static void Main() {
var d = new Dictionary<string, int> { ["a"] = 1, ["b"] = 2 };
foreach (var (key, val) in d)
Console.WriteLine($"{key}={val}");
}
}العد باستخدام Dictionary
من الاستخدامات الشائعة حساب عدد مرات الظهور. لكل عنصر، زِد عداده، وابدأ من الصفر إذا كان جديدًا.
يعمل هذا النمط في O(n) لعدد n من العناصر، لأن كل عملية بحث وتحديث تكلفتها O(1)، بدلًا من O(n تربيع) إذا فحصت قائمةً في كل مرة.
using System;
using System.Collections.Generic;
class Program {
static void Main() {
var counts = new Dictionary<char, int>();
foreach (char c in "banana")
counts[c] = counts.GetValueOrDefault(c) + 1;
Console.WriteLine(counts['a']);
}
}مساواة المفاتيح مهمة
تعتمد عمليات البحث على GetHashCode وEquals لنوع المفتاح. وتعمل الأنواع المضمنة وstring مباشرةً دون إعداد إضافي.
بالنسبة إلى مفاتيح الأصناف المخصصة، أعد تعريف كلتا الدالتين (أو استخدم record)، وإلا فستحصل مفاتيح تبدو متساوية على قيم تجزئة مختلفة، وتفشل عمليات البحث.
var byName = new Dictionary<string, int>(
System.StringComparer.OrdinalIgnoreCase);
byName["Hi"] = 1;
bool found = byName.ContainsKey("HI"); // trueاختيار نوع القيمة
يمكن أن تكون القيم من أي نوع، بما في ذلك القوائم. يجمع Dictionary<string, List<int>> قيمًا متعددة تحت مفتاح واحد.
عند الإدراج في بنية كهذه، أنشئ القائمة الداخلية عند أول استخدام، ثم أضف القيمة إليها. وبذلك تبني خريطة مجمعة متعددة القيم.
var groups = new Dictionary<string, List<int>>();
void Add(string k, int v) {
if (!groups.TryGetValue(k, out var list))
groups[k] = list = new List<int>();
list.Add(v);
}تحقق سريع
اختر الطريقة الأكثر أمانًا لقراءة مفتاح قد يكون مفقودًا.
مراجعة
يوفر Dictionary<K,V> عمليات بحث وإدراج وإزالة حسب المفتاح بكلفة O(1) في المتوسط، ويعتمد في ذلك على جدول تجزئة.
فضّل TryGetValue على المفهرس الذي يرمي استثناءً، وحافظ على تفرد المفاتيح، وتأكد من أن أنواع المفاتيح المخصصة تطبق المساواة وحساب التجزئة بطريقة صحيحة. ترتيب التكرار غير محدد.
الأسئلة الشائعة
هل درس «البحث في Dictionary» مجاني؟
نعم — نص درس «البحث في Dictionary» كامل متاح مجاناً هنا على الويب. لتمرينه بشكل تفاعلي (محرر أكواد مدمج ومدرس ذكاء اصطناعي متاح 24/7) وفتح باقي دورة C# Academy، انتقل إلى CoddyKit PRO. تتضمن دورة C# Academy 4 دروس في المجموع.
ماذا ستتعلم في «البحث في Dictionary»؟
وصول سريع إلى قيم المفاتيح تتمرن على C# Academy مع أكواد عملية تشغلها مباشرة في المتصفح، ومدرس ذكاء اصطناعي متاح 24/7 يجيب على أسئلتك أثناء عملك.
هل أحتاج إلى خبرة سابقة لأبدأ C# Academy؟
لا تُشترط خبرة سابقة. C# Academy على CoddyKit منظم للمبتدئين حتى المتقدمين، لذا يمكنك البدء من هنا أو من البداية والتقدم بسرعتك الخاصة. هذا هو الدرس 2 من أصل 4.
كم من الوقت يستغرق درس «البحث في Dictionary»؟
معظم دروس CoddyKit تستغرق حوالي 5–10 دقائق. كل منها موجز وتفاعلي، لذا تحرز تقدماً مستمراً وتستأنف من حيث توقفت عبر الويب والتطبيق.
هل يمكنني كتابة وتشغيل أكواد في درس C# Academy هذا؟
نعم. كل درس في C# Academy يتضمن محرر أكواد مدمج، لذا تكتب وتشغل أكواداً حقيقية مباشرة في متصفحك وتحصل على تعليقات فورية من الذكاء الاصطناعي — بدون إعداد محلي.
جميع الدروس في هذه الدورة
- استخدام List عمليًا
- البحث في Dictionary
- HashSet والتفرّد
- اختيار مجموعة