C# Hashtable مع أمثلة

⚡ ملخص ذكي

Hashtable في لغة C# عبارة عن مجموعة من مساحة اسم System.Collections تقوم بتخزين البيانات على شكل أزواج مفتاح-قيمة، حيث يرتبط كل مفتاح فريد بقيمة معينة ويوفر المفتاح بحثًا سريعًا عن تلك القيمة المخزنة.

  • 📚 أزواج المفتاح والقيمة: يخزن جدول التجزئة قيمتين لكل عنصر، المفتاح وقيمته، بدلاً من القيمة الواحدة التي يحتفظ بها المكدس أو قائمة المصفوفة.
  • ➕ إضافة العناصر: تقوم طريقة الإضافة بإدراج مفتاح وقيمة معًا، ويجب أن يكون كل مفتاح داخل جدول التجزئة فريدًا.
  • ؟؟؟؟ يحتوي على المفتاح ويحتوي على القيمة: تُرجع هذه الطرق القيمة true أو false حتى تتمكن من اختبار ما إذا كان المفتاح أو القيمة موجودًا بالفعل.
  • 🔁 قيم القراءة: تتيح لك خاصية Keys مع ICollection، أو حلقة DictionaryEntry، قراءة كل قيمة مخزنة بدورها.
  • 🛠️ الأساليب والخصائص: تقوم وظائف الإزالة والمسح والعد والمفاتيح والقيم بإدارة وفحص محتويات جدول التجزئة.
  • 🤖 مساعدة الذكاء الاصطناعي: يقوم GitHub Copilot بإنشاء أكواد Hashtable، بينما يفضل C# و ML.NET الحديثان استخدام Dictionary العام لبيانات المفتاح والقيمة الآمنة من حيث النوع.

جدول التصنيف C#

ما هو Hashtable في C#؟

جدول التجزئة عبارة عن مجموعة خاصة تُستخدم لتخزين عناصر القيمة الأساسية. لذلك بدلاً من تخزين قيمة واحدة فقط مثل المكدس وقائمة المصفوفات وقائمة الانتظار، يقوم جدول التجزئة بتخزين قيمتين. تشكل هاتان القيمتان عنصرًا في جدول التجزئة.

فيما يلي بعض الأمثلة لكيفية ظهور قيم جدول التجزئة.

{ "001" , ".Net" }
{ "002" , ".C#" }
{ "003" , "ASP.Net" }

أعلاه لدينا 3 أزواج قيمة رئيسية. مفاتيح كل عنصر هي 001، 002 و 003 على التوالي. قيم كل زوج من القيمة الرئيسية هي ".شبكة"و"C#" و"ASP.Net" على التوالي.

دعونا نلقي نظرة على العمليات المتاحة لمجموعة Hashtable بمزيد من التفصيل.

إعلان الهاشتابل

يظهر إعلان Hashtable أدناه. يتم إنشاء Hashtable بمساعدة نوع بيانات Hashtable. يتم استخدام الكلمة الأساسية "جديد" لإنشاء كائن Hashtable. ثم يتم تعيين الكائن إلى المتغير ht.

Hashtable ht = new Hashtable()

إضافة عناصر إلى Hashtable

يتم استخدام طريقة الإضافة لإضافة عنصر إلى طابور. ويرد أدناه بناء الجملة العام للبيان

HashTable.add("key","value")

مثال 1:

تذكر أن كل عنصر في جدول التجزئة يتكون من قيمتين، إحداهما هي المفتاح والأخرى هي القيمة.

الآن، دعونا نرى هذا يعمل على مستوى التعليمات البرمجية. ستتم كتابة كافة التعليمات البرمجية المذكورة أدناه إلى تطبيق وحدة التحكم لدينا.

ستتم كتابة الكود في ملف Program.cs الخاص بنا. في البرنامج أدناه، سنكتب الكود لنرى كيف يمكننا استخدام الطرق المذكورة أعلاه.

في الوقت الحالي، في مثالنا، سننظر فقط في كيفية إنشاء جدول تجزئة وإضافة عناصر إليه وعرضها وفقًا لذلك.

جدول التجزئة في C#

using System;
using System.Collections;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Threading.Tasks;

namespace DemoApplication
{
 class Program
 {
  static void Main(string[] args)
  {
   Hashtable ht = new Hashtable();
   ht.Add("001",".Net");
   ht.Add("002","C#");
   ht.Add("003","ASP.Net");

   ICollection keys = ht.Keys;

   foreach (String k in keys)
   {
    Console.WriteLine(ht[k]);
   }
    Console.ReadKey();
   }
 }
}

Code تفسير:-

  1. أولاً، نعلن عن المتغير القابل للتجزئة باستخدام نوع البيانات Hashtable باستخدام الكلمة الأساسية "جديد". اسم المتغير الذي يحدده هو "ht".
  2. نقوم بعد ذلك بإضافة عناصر إلى جدول التجزئة باستخدام طريقة الإضافة. تذكر أننا بحاجة إلى إضافة كل من عنصر المفتاح والقيمة عند إضافة شيء ما إلى جدول التجزئة.
  3. لا توجد طريقة مباشرة لعرض عناصر جدول التجزئة.
    • لعرض جدول التجزئة، نحتاج أولاً إلى الحصول على قائمة المفاتيح (001، 002، 003) من جدول التجزئة.
    • ويتم ذلك عبر واجهة ICollection. هذا نوع بيانات خاص يمكن استخدامه لتخزين مفاتيح المجموعات القابلة للتجزئة. نقوم بعد ذلك بتعيين مفاتيح المجموعة القابلة للتجزئة إلى "المفاتيح" المتغيرة.
  4. بعد ذلك، بالنسبة لكل قيمة مفتاح، نحصل على القيمة المرتبطة بها في جدول التجزئة باستخدام العبارة ht[k].

إذا تم إدخال الكود أعلاه بشكل صحيح وتم تشغيل البرنامج، فسيتم عرض الإخراج التالي.

الإخراج:

جدول التجزئة في C#

دعونا نلقي نظرة على بعض الطرق الإضافية المتاحة لجداول التجزئة.

يحتوي على مفتاح

تُستخدم هذه الطريقة لمعرفة ما إذا كان هناك مفتاح موجود في Hashtable. وفيما يلي بناء الجملة العام لهذا البيان. سترجع العبارة صحيحًا إذا كان المفتاح موجودًا، وإلا فسوف تُرجع القيمة خطأ.

Hashtable.Containskey(key)

يحتوي على قيمة

تُستخدم هذه الطريقة لمعرفة ما إذا كانت هناك قيمة موجودة في جدول التجزئة. وفيما يلي بناء الجملة العام لهذا البيان. سترجع العبارة صحيحًا إذا كانت القيمة موجودة، وإلا فإنها سترجع القيمة خطأ.

Hashtable.ContainsValue(value)

مثال 2:

دعونا نغير الكود الموجود في ملفنا تطبيق وحدة التحكم لعرض كيف يمكننا استخدام طريقة "Containskey" و"ContainsValue".

جدول التجزئة في C#

using System;
using System.Collections;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Threading.Tasks;

namespace DemoApplication
{
 class Program
 {
  static void Main(string[] args)
  {
   Hashtable ht = new Hashtable();
   ht.Add("001",".Net");
   ht.Add("002","C#");
   ht.Add("003","ASP.Net");

   Console.WriteLine(ht.ContainsKey("001"));
   Console.WriteLine(ht.ContainsValue("C#"));
   Console.ReadKey();
   }
 }
}

Code تفسير:-

  1. أولاً، نستخدم طريقة يحتوي على مفتاح لمعرفة ما إذا كان المفتاح موجودًا في جدول التجزئة. ستعود هذه الطريقة صحيحة إذا كان المفتاح موجودًا في جدول التجزئة. يجب أن تعود هذه الطريقة صحيحة نظرًا لوجود المفتاح في جدول التجزئة.
  2. نستخدم بعد ذلك طريقة يحتوي على قيمة لمعرفة ما إذا كانت القيمة موجودة في جدول التجزئة. ستعيد هذه الطريقة القيمة "صحيح" نظرًا لوجود القيمة في جدول التجزئة.

إذا تم إدخال الكود أعلاه بشكل صحيح وتم تشغيل البرنامج، فسيتم عرض الإخراج التالي.

الإخراج:

جدول التجزئة في C#

من الإخراج، يمكنك أن ترى بوضوح أن كلا من المفتاح والقيمة التي يتم البحث عنها موجودة في جدول التجزئة.

كيفية تكرار عناصر جدول التجزئة في لغة C#

تقرأ الأمثلة أعلاه القيم من خلال مجموعة المفاتيح، ولكن يمكن استعراض جدول التجزئة بطريقة أكثر سلاسة. تُتيح لك حلقة foreach على مدخل القاموس الحصول على المفتاح والقيمة لكل عنصر معًا في تمريرة واحدة، وهي الطريقة الأكثر شيوعًا لقراءة جدول التجزئة.

الخطوة 1) أنشئ جدول تجزئة وأضف إليه ثلاثة أزواج من المفاتيح والقيم.

الخطوة 2) قم بالتكرار على جدول التجزئة باستخدام متغير DictionaryEntry، ثم اقرأ خصائص المفتاح والقيمة لكل إدخال.

using System;
using System.Collections;

namespace DemoApplication
{
 class Program
 {
  static void Main(string[] args)
  {
   Hashtable ht = new Hashtable();
   ht.Add("101", "Java");
   ht.Add("102", "Python");
   ht.Add("103", "Kotlin");

   foreach (DictionaryEntry entry in ht)
   {
    Console.WriteLine(entry.Key + " - " + entry.Value);
   }
   Console.ReadKey();
  }
 }
}

Code تفسير:-

  1. يتم إنشاء جدول تجزئة باسم ht، ويتم إدخال ثلاثة أزواج من المفاتيح والقيم باستخدام طريقة الإضافة.
  2. تقوم حلقة foreach بتعيين كل عنصر إلى DictionaryEntry، حيث تكشف خصائص Key و Value الخاصة به عن نصفي الزوج.

عند تشغيل البرنامج، يقوم بطباعة كل مفتاح بجوار قيمته، مثل 101 – Javaنظرًا لأن جدول التجزئة لا يحتفظ بترتيب الإدخال، فقد تظهر الأزواج بترتيب مختلف عن ترتيب إضافتها. لقراءة المفاتيح فقط، استخدم حلقة تكرارية على مجموعة المفاتيح، ولقراءة القيم فقط، استخدم حلقة تكرارية على مجموعة القيم.

طرق وخصائص جداول التجزئة في لغة C#

تُوفّر فئة Hashtable مجموعة صغيرة من الدوال والخصائص التي تُغطي تقريبًا جميع المهام التي قد تحتاجها، بدءًا من إضافة الأزواج وحذفها وصولًا إلى التحقق من العضوية وحساب العناصر. فيما يلي قائمة بأهم هذه الخصائص.

فريقنا النوع الوصف
أضف (المفتاح، القيمة) الأسلوب يُدرج زوجًا جديدًا من المفتاح والقيمة؛ يجب أن يكون المفتاح فريدًا.
إزالة (مفتاح) الأسلوب يحذف العنصر الذي يطابق المفتاح المحدد.
واضح() الأسلوب يزيل كل زوج من المفتاح والقيمة من جدول التجزئة.
يحتوي على المفتاح (key) الأسلوب تُرجع القيمة "صحيح" عند وجود المفتاح المحدد.
يحتوي على القيمة (القيمة) الأسلوب تُرجع القيمة "صحيح" عند وجود القيمة المُعطاة.
العد التنازلي الممتلكات يحصل على عدد أزواج المفاتيح والقيم المخزنة.
مفاتيح الممتلكات يُعيد مجموعة من جميع المفاتيح.
القيم الممتلكات يُعيد مجموعة من جميع القيم.

لأن كل مفتاح يتم تجزئته، فإن ContainsKey والفهرس يحددان موقع عنصر في وقت ثابت تقريبًا، وهو ما يجعل Hashtable مفيدًا جدًا لعمليات البحث السريعة.

الفرق بين جدول التجزئة والقاموس في لغة C#

يخزن كل من جدول التجزئة والقاموس أزواج المفاتيح والقيم، وكلاهما ينتمي إلى عائلة C# الأوسع مجموعاتالفرق المهم هو سلامة النوع، وهذا الفرق هو الذي يحدد أيهما يجب عليك استخدامه في الكود الجديد.

  • أمان النوع: يخزن جدول التجزئة كل مفتاح وقيمة ككائن، بينما يخزن القاموس هو عام، لذا يقوم المترجم بفحص الأنواع التي تستخدمها.
  • مساحة الاسم: يوجد Hashtable في System.Collections، بينما يوجد Dictionary في System.Collections.Generic.
  • Boxجي: يقوم جدول التجزئة بتخزين أنواع القيم مثل int، لكن القاموس العام يخزنها مباشرة ويتجنب تلك التكلفة.
  • الأداء: عادةً ما يكون القاموس أسرع لأنه لا يحتاج إلى تحويل من كائن عند قراءة قيمة.
  • أمان الخيوط: يقدم موقع Hashtable Syncغلاف متزامن لكاتب واحد مع العديد من القراء، بينما يختار الكود المتزامن عادةً ConcurrentDictionary.

بالنسبة لأي مشروع جديد، فإن القاموس العام هو الخيار الموصى به، ويظهر جدول التجزئة غير العام بشكل رئيسي في التعليمات البرمجية القديمة.

الأسئلة الشائعة

تقوم دالة Remove بحذف العنصر ذي المفتاح المحدد، وتقلل عدد العناصر بمقدار واحد. إذا لم يكن المفتاح موجودًا، فلن يحدث شيء، لذا يُنصح باستدعاء دالة ContainsKey أولًا للتأكد من وجود المفتاح.

لا. يجب أن يكون كل مفتاح في جدول التجزئة فريدًا. استدعاء دالة الإضافة (Add) باستخدام مفتاح موجود مسبقًا يُسبب خطأً من نوع ArgumentException. مع ذلك، يمكنك تخزين القيمة نفسها تحت عدة مفاتيح مختلفة دون أي خطأ.

يدعم جدول التجزئة كاتبًا واحدًا مع العديد من القراء بأمان. ولتعدد مسارات الكتابة، استخدم جدول التجزئة لتغليفها.Synchronized، أو يفضل استخدام ConcurrentDictionary من System.Collections.Concurrent، الذي يتعامل مع عمليات القراءة والكتابة المتزامنة بدون أقفال خارجية.

يستغرق البحث عن قيمة باستخدام مفتاح وقتًا ثابتًا تقريبًا O(1) في المتوسط، لأن المفتاح يُجزأ للعثور على خانته. قد تؤدي تصادمات التجزئة الشديدة إلى إبطاء العملية، لكن هذا نادر الحدوث مع المفاتيح الموزعة جيدًا.

قد تكون القيمة فارغة، لكن لا يمكن أن يكون المفتاح كذلك. تمرير مفتاح فارغ إلى دالة الإضافة أو الفهرسة يُسبب استثناء ArgumentNullException. يجب أن يكون كل مفتاح فريدًا ولا يجب أن يتغير أثناء تخزينه.

لا يحتفظ جدول التجزئة بترتيب، لذا لا يمكن فرزه في مكانه. انسخ مفاتيحه إلى قائمة أو مصفوفة، ثم رتب تلك القائمة، ثم اقرأ القيم حسب المفتاح. أما القائمة المرتبة، فتحتفظ بترتيب عناصرها تلقائيًا.

نعم. يقوم GitHub Copilot بكتابة تعريفات Hashtable، واستدعاءات Add، وحلقات DictionaryEntry من تعليق قصير أو اسم دالة. وغالبًا ما يقترح استخدام Dictionary العام بدلاً من ذلك، لأنه المجموعة الموصى بها لبرامج C# الجديدة.

تتدفق بيانات التدريب في ML.NET عبر مجموعات مُصنفة ومسار IDataView بدلاً من جدول التجزئة. ومع ذلك، لا تزال خرائط المفتاح والقيمة القائمة على التجزئة تدعم عمليات البحث عن الميزات، وتشفير المفردات، والتخزين المؤقت حول نموذج التعلم الآلي.

تلخيص هذه التدوينة بـ: