القواميس (Dictionaries)

مقدمة

القواميس (Dictionaries) هي أحد هياكل البيانات الهامة، وأكثرها شهرةً بعد المصفوفات، تستخدم في تجميع البيانات كما تفعل المصفوفات بالضبط، ولكن الفرق أن القواميس تجمّع البيانات بأسلوب مفتاح > قيمة.

أهمية القواميس

مشكلة تخزين بيانات المنشور

درسنا في المصفوفات كيفية تجميع البيانات، فمثلاً لو لدينا عدد كبير من المنشورات مثلاً يمكننا تخزينها (تجميعها) في مصفوفة (array) مثلاً: var posts = ["post 1", "post 2", "post 3"]

في المثال السابق قمنا بتخزين ثلاثة منشورات في مصفوفة، المنشور مجرد "نص" (string) يمكن تجميعه في مصفوفة من النصوص، أما الحقيقة أن اﻷمر أكثر تعقيداً، فالمنشور ليس مجرد نصّاً، بل هناك لكل منشور بعض البيانات اﻷخرى المرتبطة به، على سبيل المثال (ناشر المنشور، وقت النشر، عدد اﻹعجابات، عدد المشاهدات، عدد التعليقات، ...الخ) وكل منشور يجب أن يحتوي على هذه البيانات، فكيف نقوم بتخزينها في متغير للتعامل معها في البرنامج؟ ولنفرض أن لدينا عدد كبير من المنشورات، كيف يمكننا إنشاء مصفوفة تحوي كل المنشورات، وكل منشور يحوي بياناته كاملةً؟ هنا يبدأ اﻹحتياج للقواميس بشدة وهي من أكثر المفاهيم البرمجية التي ستستخدمها في المشاريع البرمجية الحقيقية خصوصا تلك التي تتعامل مع بيانات كالشبكات اﻹجتماعية والمتاجر اﻹلكترونية.

مشكلة تخزين بيانات المستخدم

لنفرض أن لديك مستخدمين في البرنامج، لكل مستخدم اسم وبريد إلكتروني وبعض البيانات اﻷخرى، كيف يمكننا تخزينها في متغير واحد؟ والوصول لإسمه أو بريده بسهولة؟

القواميس (Dictionaries)

يستخدم القاموس لتخزين بيانات متعددة بأسلوب مفتاح > قيمة (key > value)، فمثلاً في المصفوفات كنا نخزن البيانات هكذا: [100, 20] عن طريق القيمة فقط، ويكون المفتاح (key) هو الترتيب (index)، أما في القواميس نعرّف بأنفسنا المفتاح، فمثلاً نريد المفتاح ["likes"] قيمته تساوي 100 والمفتاح ["comments"] قيمته تساوي 20 بحيث إذا أردنا الوصول مثلاً لعدد إعجابات المنشور نكتب post["likes"] أو إذا أردنا الوصول لعدد تعليقات المنشور نكتب post["comments"]

مصطلح القواميس

يختلف اسم القواميس بشكل كبير بين اللغات، وكذلك تختلف طريقة كتابتها لكن المفهوم واحد، وأهميته واحدة، واستخداماته واحدة تقريبا، وهذا ما يهمنا... لذلك دراستك له بأي لغة يجعلك قادر على تعلمه في أي لغة أخرى في دقائق.. لكننا سنطلق عليه القاموس (Dictionaries)، وله عدة أسماء أخرى:

  • المصفوفة اﻹرتباطية (Associative Array)
  • جدول تجزئة (Hash Table)

القواميس برمجياً

تختلف القواميس بشدة من لغة لأخرى من حيث كتابتها وإسمها وبعض التفاصيل اﻷخرى، ومن هذه اﻹختلافات أن هناك لغات كلغة جافاسكريبت لا يوجد فيها قواميس بنفس مفهومها ولكن يوجد فيها الكائنات (objects) وهي مفهوم كبير ومتقدم جداً وله استخدامات أوسع وأكبر من القواميس، لكن من استخداماته في جافاسكريبت تخزين البيانات بأسلوب مفتاح > قيمة لذلك نستخدمه كأنه قواميس، لكنه في الحقيقة ليس قاموساً

في لغة جافاسكريبت تؤدي الكائنات (objects) دور القواميس، أما في لغة Java هناك Hash Table يمكنك استخدامه كقاموس ﻷنه سيؤدي نفس غرضها، وفي لغة PHP هناك المصفوفات اﻹرتباطية (Associative Arrays)، وفي لغة Python هناك القاموس (Dictionary) بنفس اﻹسم، كل ما ذكرنا يمكن استخدامه لتخزين البيانات بأسلوب مفتاح > قيمة، فاﻹستخدام واحد تقريباً لذلك عند دراسة أساسيات أي لغة ستتعلم فقط طريقة الكتابة والفروقات البسيطة في المصطلحات.

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

إنشاء القاموس

كما قلنا في لغة جافاسكريبت التي نستخدمها في الشرح واﻷمثلة يتم استخدام الكائنات (Objects) كقواميس لذلك لن تجد مصطلح قاموس في جافاسكريبت، هناك كائنات فقط...

يتم كتابة الكائن في جافاسكريبت بالطريقة التالية:

{name: "Dalil Mobarmg", lesson: "Dictionaries"}

في المثال السابق أنشأنا كائن يحتوي على عنصرين، عنصر مفتاحه name وقيمته "Dalil Mobarmg" وعنصر مفتاحه lesson وقيمته "Dictionaries" وهذا الكائن يعمل بالضبط كأنه قاموس.

في القواميس العنصر عبارة عن مفتاح وقيمة، في الكائنات في جافاسكريبت يتم كتابة المفتاح ثم : ثم القيمة، ويفصل بين كل عنصر واﻵخر علامة ,

استخدم اﻷقواس المعقوفة {} بدلاً من اﻷقواس []

الوصول لعناصر القاموس

كما نفعل مع المصفوفات، يمكننا الوصول لعناصرها عن طريق المفتاح (key):

var test = {name: "Dalil Mobarmg", lesson: "Dictionaries"};

console.log(test["name"]);
console.log(test["lesson"]);
ناتج التشغيل Dalil Mobarmg
Dictionaries

إضافة عنصر إلى القاموس

يمكن إضافة عنصر للقاموس كما نفعل مع المصفوفات بكل بساطة:

var test = {};
test["name"] = "Mohamed";
console.log(test["name"]);
ناتج التشغيل Mohamed

تعديل عنصر في القاموس

var test = {name: "Mohamed"};
console.log(test["name"]);

test["name"] = "Ebrahim";
console.log(test["name"]);
ناتج التشغيل Mohamed
Ebrahim

حذف عنصر من القاموس

تختلف هذه الطريقة من لغة لأخرى، وسنذكر مثال بلغة جافاسكريبت

var test = {name: "Mohamed"};
console.log(test["name"]);

delete test["name"];
console.log(test["name"]);
ناتج التشغيل Mohamed
undefined

undefined في جافاسكريبت هي أحد أنواع البيانات، وتعني "غير معرف"، فمثلاً إن قمت بطباعة قيمة متغير غير موجود سيتم طباعة undefined لكن هذا النوع من البيانات غير موجود في أي لغة أخرى تقريباً، في معظم اللغات إن قمت بطباعة متغير غير موجود أو مثلاً عنصر غير موجود في القاموس كما فعلنا سيُعطي المفسر خطأ

حل مشكلة تخزين بيانات المنشور

اﻵن يمكننا حل مشكلة تخزين بيانات المنشور المذكورة في بداية الدرس:

var post = {content: "post 1", likes: 100, comments: 20, user: "Ebrahim Maher"}

أو ممكن كتابتها بالشكل التالي لسهولة القراءة والتنسيق:
var post = {
  content: "post 1",
  likes: 100,
  comments: 20,
  user: "Ebrahim Maher"
}

console.log(post["content"]);
console.log(post["likes"]);
ناتج التشغيل post 1
100

قواميس متعددة

اﻵن يمكننا تخزين بيانات منشور، لكن لنفرض أن لدينا الكثير من المنشورات، ونريد تجميعهم في متغير واحد، كيف نجمعهم؟ بالتأكيد باستخدام المصفوفات، يمكننا إنشاء مصفوفة بداخلها أي عدد من القواميس، بحيث يكون لدينا مصفوفة بداخلها الكثير من المنشورات، وكل منشور عبارة عن قاموس

var posts = [
  {content: "post 1", likes: 100},
  {content: "post 2", likes: 150},
  {content: "post 3", likes: 40},
  {content: "post 4", likes: 70},
];

اﻵن لدينا مصفوفة، بداخلها 4 قواميس، يمكن التعامل مع المصفوفة posts كأي مصفوفة، يمكن الوصول للعنصر اﻷول فيها عن طريق posts[0] ويمكن الوصول لكل عناصرها باستخدام الحلقات التكرارية، فمثلاً إذا أردنا الوصول للمنشور اﻷول يمكننا استخدام الكود التالي:

var post = posts[0];
console.log(post["content"]);
console.log(post["likes"]);
ناتج التشغيل post 1
100

أنشأنا متغير اسمه post وقيمته تساوي العنصر اﻷول من المصفوفة posts وبالتالي قيمته تساوي القاموس: {content: "post 1", likes: 100}، وتم طباعة قيمة المفتاح ["content"] من القاموس post، ثم تم طباعة قيمة المفتاح ["likes"]

طباعة محتوى كل المنشورات

نريد طباعة المحتوى (content) لكل المنشورات الموجودة في المصفوفة posts، يمكننا استخدام الحلقات التكرارية كما تعلمنا في درس المصفوفات للوصول لكل المنشورات (العناصر) الموجودة بداخل المصفوفة posts:

var posts = [
  {content: "post 1", likes: 100},
  {content: "post 2", likes: 150},
  {content: "post 3", likes: 40},
  {content: "post 4", likes: 70},
];

var i = 0;
while (i < posts.length){
  var post = posts[i];
  console.log( post["content"] );
  i = i + 1;
}
ناتج التشغيل post 1
post 2
post 3
post 4

مثال واقعي على القواميس

عندما تستخدم موقع تواصل إجتماعي، أو تطبيق مراسلة، وترسل رسالة لشخص ما، هل تعلم أن هذه الرسالة برمجياً تُخزن في قاموس؟ بالضبط كما فعلنا في اﻷمثلة السابقة، تكون مصفوفة بداخلها قواميس متعددة، لكل رسالة تظهر أمامك قاموس، يحتوي على عدة عناصر منها اسم المرسل ورابط صورته ومحتوى الرسالة ووقت اﻹرسال، بهذه الطريقة تُخزن البيانات الهامة في التطبيقات كالمنشورات، التعليقات، الرسائل، المنتجات ... الخ وفقط في صفحة الويب أو في واجهة التطبيق عندما نريد أن نصل للصورة المرتبطة بالرسالة مثلاً نكتب message["photo"] على اعتبار أن الرسالة مخزنة في متغير message وكذلك الصورة مفتاحها "photo"

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

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

لقد تعمدنا في هذا الدرس شرح المفهوم فقط، ولم نتعمق في التفاصيل ﻷنها تختلف جداً بين اللغات، وإن كانت هناك أمور لم تفهمها في الدرس لا مشكلة، ستتعلمها لاحقاً عندما تدرس أي لغة برمجة، ستتعمق حينها في تفاصيلها واﻹختلافات بينها وبين اللغات اﻷخرى ومصطلحاتها الخاصة، لكن ما ذكرناه هنا هو شرح لمفهوم القواميس، شرح لهيكل البيانات الذي يستخدم في تخزين البيانات بأسلوب مفتاح > قيمة

المساهمين

وجدت خطأ أو تريد المساهمة في محتوى الدرس؟ عدل الصفحة على Github