تخطَّ إلى المحتوى

المصفوفات والقوائم في C#‎: Array و List و LINQ

الدرس 6 من 11 · C#

قائمة اللاعبين في لعبة، وسلة المشتريات في متجر، ودرجات طلاب الفصل: كلها مجموعات من البيانات. في هذا الدرس ستتعرف على المصفوفات في C#‎، ثم على القائمة المرنة List والقاموس Dictionary، ثم على أداة قوية جداً تميّز C#‎ اسمها LINQ، تتيح لك تصفية البيانات وتحويلها في سطر واحد.

int[] scores = { 85, 92, 78, 64 };
Console.WriteLine(scores[0]);
Console.WriteLine(scores.Length);
scores[1] = 95;
Console.WriteLine(string.Join(", ", scores));
الناتج
85
4
85, 95, 78, 64
  • int[]: مصفوفة أعداد صحيحة، والترقيم يبدأ من صفر.
  • Length: عدد العناصر.
  • string.Join(", ", scores): يجمع العناصر في نص واحد بينها فاصل، وهي أفضل طريقة لطباعتها.

لماذا لا نطبعها مباشرة؟ لأن Console.WriteLine(scores) تطبع اسم نوعها فقط: System.Int32[]!

والمصفوفة ثابتة الحجم: لا إضافة ولا حذف. وعند إنشائها بحجم فقط، تأخذ قيماً افتراضية:

int[] counts = new int[4];
Console.WriteLine(string.Join(", ", counts));
الناتج
0, 0, 0, 0

صفر للأرقام، و false لـ bool، و null للنصوص.

Array.Sort(scores);
Console.WriteLine(string.Join(", ", scores));
Console.WriteLine(scores.Sum());
Console.WriteLine(scores.Max());
Console.WriteLine(scores.Average());
الناتج
64, 78, 85, 95
322
95
80.5

Array.Sort ترتب المصفوفة نفسها، و Sum و Max و Average من مكتبة LINQ التي ستتعرف عليها بعد قليل.

القائمة List: المصفوفة المرنة

Section titled “القائمة List: المصفوفة المرنة”

في أغلب البرامج الحقيقية ستستخدم List بدلاً من المصفوفة، لأنها تكبر وتصغر:

List<string> tasks = new List<string>();
tasks.Add("مذاكرة");
tasks.Add("رياضة");
tasks.Add("قراءة");
tasks.Remove("رياضة");
tasks[0] = "مذاكرة C#";
Console.WriteLine(string.Join(" | ", tasks));
Console.WriteLine(tasks.Count);
Console.WriteLine(tasks.Contains("قراءة"));
الناتج
مذاكرة C# | قراءة
2
True
  • List<string>: قائمة نصوص، والنوع بين < >.
  • Add للإضافة، و Remove للحذف بالقيمة، و RemoveAt للحذف بالرقم.
  • Count للعدد (وليس Length كالمصفوفة).

وفي C#‎ الحديثة يمكن إنشاء القائمة باختصار بالأقواس المربعة: List<int> grades = [85, 92, 78, 64, 50];

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

LINQ: استعلامات على البيانات

Section titled “LINQ: استعلامات على البيانات”

LINQ (تُنطق «لينك») مجموعة دوال تعمل على أي مجموعة، وتستقبل غالباً Lambda:

List<int> grades = [85, 92, 78, 64, 50];
var passed = grades.Where(g => g >= 75).ToList();
Console.WriteLine(string.Join(", ", passed));
var bonus = grades.Select(g => g + 5);
Console.WriteLine(string.Join(", ", bonus));
Console.WriteLine(grades.Count(g => g < 60));
Console.WriteLine(string.Join(", ", grades.OrderByDescending(g => g)));
الناتج
85, 92, 78
90, 97, 83, 69, 55
1
92, 85, 78, 64, 50
الدالة وظيفتها
Where تصفية: احتفظ بما يحقق الشرط
Select تحويل: طبّق عملية على كل عنصر
Count(شرط) عد العناصر التي تحقق الشرط
OrderBy و OrderByDescending ترتيب تصاعدي وتنازلي
Sum و Average و Max و Min الإحصاءات
First و Any أول عنصر، وهل يوجد أي عنصر يحقق شرطاً

LINQ لا تغيّر القائمة الأصلية، بل تُرجع نتيجة جديدة. و ToList() تحوّل النتيجة إلى قائمة عادية.

أزواج مفتاح ← قيمة، للبحث السريع بالمفتاح:

var prices = new Dictionary<string, int>
{
["قلم"] = 5,
["كراسة"] = 15,
["مسطرة"] = 7
};
Console.WriteLine(prices["قلم"]);
foreach (var (item, price) in prices)
{
Console.WriteLine($"{item}: {price} جنيه");
}
Console.WriteLine(prices.ContainsKey("ممحاة"));
Console.WriteLine(prices.Values.Sum());
الناتج
5
قلم: 5 جنيه
كراسة: 15 جنيه
مسطرة: 7 جنيه
False
27

انتبه: قراءة مفتاح غير موجود مثل prices["ممحاة"] تعطي خطأ KeyNotFoundException. افحص أولاً بـ ContainsKey، أو استخدم TryGetValue.

المصفوفة ثنائية الأبعاد

Section titled “المصفوفة ثنائية الأبعاد”
int[,] grid = { { 1, 2, 3 }, { 4, 5, 6 } };
Console.WriteLine(grid[1, 2]);
الناتج
6

في C#‎ تُكتب المصفوفة ثنائية الأبعاد بفاصلة داخل القوسين: [صف, عمود]. مفيدة للوحات الألعاب والجداول.

  1. أنشئ List<string> لقائمة مشتريات، أضف 5 عناصر، واحذف واحداً، واطبعها بـ string.Join.
  2. من قائمة درجات، اطبع بـ LINQ: عدد الناجحين، ومتوسط درجات الناجحين فقط، وأعلى 3 درجات (تلميح: OrderByDescending ثم Take(3)).
  3. أنشئ Dictionary لأسعار 4 منتجات، واطبع أغلى منتج.
  4. تحدٍّ: احسب عدد مرات تكرار كل كلمة في قائمة كلمات باستخدام Dictionary<string, int>.
  • رقم خارج الحدود: scores[10] تعطي خطأ Index was outside the bounds of the array. آخر رقم هو Length - 1.
  • الخلط بين Length و Count: المصفوفة Length، والقائمة Count.
  • قراءة مفتاح غير موجود في Dictionary: افحص بـ ContainsKey أولاً.

سؤال

ما ناتج new List<int> { 3, 8, 5 }.Where(x => x > 4).Count()؟

سؤال

ماذا يطبع Console.WriteLine(arr) إذا كانت arr مصفوفة أعداد صحيحة؟

  • المصفوفة int[] ثابتة الحجم، و Length عددها، و string.Join لطباعتها.
  • List<T> قائمة مرنة: Add و Remove و Count و Contains.
  • LINQ: Where و Select و Count و OrderBy و Sum و Average بأسطر قليلة.
  • Dictionary<K, V> للمفاتيح والقيم، وافحص المفتاح قبل قراءته.
  • int[,] مصفوفة ثنائية الأبعاد بصيغة [صف, عمود].