C# Programming

إزالة عناصر المصفوفة بكفاءة في C#

Spread the love

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

جدول المحتويات

استخدام LINQ لإزالة فعالة

يوفر LINQ (Language Integrated Query) الحل الأكثر مباشرة. يُفلتر الشرط Where() العناصر بناءً على شرط معين، مما يُنشئ مصفوفة جديدة تحتوي فقط على العناصر التي تلبي الشرط. وهذا يُزيل فعليًا تلك التي لا تلبي الشرط.


int[] numbers = { 1, 2, 3, 4, 5, 6 };
int[] numbersWithoutThree = numbers.Where(n => n != 3).ToArray(); 
// numbersWithoutThree الآن تحتوي على {1, 2, 4, 5, 6}

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

أسلوب List<T>

لإزالة العناصر ديناميكيًا، List<T> أفضل. List<T> عبارة عن مجموعة قابلة لإعادة التحجيم، مما يسمح بإزالة العناصر مباشرة باستخدام أساليب مثل RemoveAt() أو Remove().


List<int> numbersList = new List<int> { 1, 2, 3, 4, 5, 6 };
numbersList.RemoveAt(2); //يزيل العنصر في الفهرس 2 (القيمة 3)
numbersList.Remove(5); //يزيل أول ظهور للرقم 5.

// للعودة إلى مصفوفة:
int[] newArray = numbersList.ToArray();

هذا الأسلوب فعال للإضافات والإزالـات المتكررة، مما يتجنب عبء إنشاء مصفوفات جديدة.

تقريب الإزالة في المكان (متقدم)

بينما لا يُمكن إجراء إزالة حقيقية في المكان باستخدام مصفوفات C#، يمكننا محاكاتها عن طريق تحويل العناصر. هذا أقل كفاءة من LINQ أو List<T> إلا في حالة التعامل مع مصفوفات كبيرة جدًا حيث يكون تقليل إنشاء مصفوفات جديدة أمرًا بالغ الأهمية. ومع ذلك، فهو أكثر تعقيدًا بكثير.


int[] numbers = { 1, 2, 3, 4, 5, 6 };
int indexToRemove = Array.IndexOf(numbers, 3);

if (indexToRemove != -1) {
    Array.Copy(numbers, indexToRemove + 1, numbers, indexToRemove, numbers.Length - indexToRemove - 1);
    Array.Resize(ref numbers, numbers.Length - 1);
}

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

الخلاصة

في معظم الحالات، يوفر استخدام طريقة Where() في LINQ أو الانتقال إلى List<T> أفضل توازن بين سهولة القراءة والكفاءة. يجب فقط النظر في طريقة “الإزالة في المكان” في حالات محددة للغاية تتعلق بالأداء مع مصفوفات كبيرة جدًا حيث يكون تقليل تخصيصات المصفوفات الجديدة ذا أهمية قصوى. يُعد إجراء قياس الأداء الشامل أمرًا بالغ الأهمية لتبرير استخدامه.

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

س: هل يمكنني إزالة عناصر متعددة باستخدام LINQ؟

ج: نعم، استخدم شرطًا أكثر تعقيدًا في تعبير لامدا Where(). على سبيل المثال، numbers.Where(n => n % 2 == 0).ToArray() يزيل الأعداد الفردية.

س: ماذا عن إزالة العناصر حسب القيمة في قائمة؟

ج: تقوم طريقة Remove() بإزالة أول ظهور لقيمة محددة.

س: أي طريقة هي الأسرع؟

ج: بشكل عام، LINQ أسرع للمصفوفات الصغيرة إلى المتوسطة الحجم. بالنسبة للمصفوفات الكبيرة جدًا، قد يكون فرق الأداء ضئيلاً، وقد تُظهر طريقة “الإزالة في المكان” (على الرغم من تعقيدها) ربما ميزة طفيفة بسبب تقليل التخصيصات. قياس الأداء ضروري لحالات محددة.

اترك تعليقاً

لن يتم نشر عنوان بريدك الإلكتروني. الحقول الإلزامية مشار إليها بـ *