كيفية حذف عنصر من شريحة في Golang: دليل كامل مع أمثلة

مدرب بايثون أونلاين للمبتدئين

تعلم Python بسهولة دون إرهاق نظري. حل مهام عملية مع التحقق التلقائي واكتب الكود مباشرة في المتصفح.

ابدأ الدورة

كيفية حذف عنصر من Slice في Golang: دليل مفصل مع أمثلة

\n\n

العمل مع الشرائح (slices) في Go هو روتين يومي لكل مطور. لكن عملية واحدة تثير تساؤلات حتى لدى مطوري Go ذوي الخبرة: حذف عنصر من الشريحة. قد يبدو الأمر بسيطًا؟ لكن في Go لا توجد دالة مدمجة delete() للشرائح كما هو الحال مع الخرائط (maps). مما يضطرنا لابتكار حلول خاصة.

\n\n

في هذه المقالة، سنستعرض جميع طرق حذف عنصر من شريحة في Golang: من الحذف البسيط حسب الفهرس إلى الحيل المتقدمة مع الحفاظ على الترتيب وتحسين الذاكرة. ستتعلم كيف تعمل الآلية الداخلية للشرائح، ولماذا لا يعمل التعيين البسيط دائمًا، وكيف تتجنب الأخطاء الشائعة.

\n\n

لماذا لا توجد دالة مدمجة لحذف العناصر من الشريحة في Go؟

\n\n

قبل الغوص في الكود، دعنا نفهم فلسفة اللغة. الشريحة (slice) في Go هي مجرد "نافذة" على المصفوفة الأساسية. إنها لا تملك البيانات، بل تشير إليها فقط. لذلك، حذف عنصر ليس مسحًا فيزيائيًا للبيانات من الذاكرة (كما في C++)، بل إعادة بناء "النافذة" باستخدام عمليات append والتقطيع (slicing) الذكية.

\n\n

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

\n\n

الطريقة 1: الحذف حسب الفهرس (مع الحفاظ على الترتيب)

\n\n

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

\n\n
package main\n\nimport "fmt"\n\nfunc removeIndex(s []int, index int) []int {\n    // ندمج الجزء قبل الفهرس مع الجزء بعد الفهرس\n    return append(s[:index], s[index+1:]...)\n}\n\nfunc main() {\n    slice := []int{1, 2, 3, 4, 5}\n    slice = removeIndex(slice, 2) // نحذف العنصر ذا الفهرس 2 (القيمة 3)\n    fmt.Println(slice) // [1 2 4 5]\n}\n
\n\n

كيف يعمل هذا؟

\n
    \n
  • s[:index] — نأخذ جميع العناصر قبل المحذوف (بدون تضمينه).
  • \n
  • s[index+1:] — نأخذ جميع العناصر بعد المحذوف.
  • \n
  • append يدمج هذين "الجزأين" في شريحة واحدة.
  • \n
\n\n

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

\n\n

الطريقة 2: الحذف حسب الفهرس (بدون الحفاظ على الترتيب) — طريقة سريعة

\n\n

إذا كان ترتيب العناصر غير مهم (مثلاً، تعمل مع مجموعة بيانات غير مرتبة)، يمكنك استخدام حيلة "الاستبدال بالعنصر الأخير":

\n\n
func removeFast(s []int, index int) []int {\n    // نستبدل العنصر المحذوف بالعنصر الأخير\n    s[index] = s[len(s)-1]\n    // نقطع الشريحة، متجاهلين العنصر الأخير\n    return s[:len(s)-1]\n}\n\nfunc main() {\n    slice := []int{1, 2, 3, 4, 5}\n    slice = removeFast(slice, 1) // نحذف العنصر ذا الفهرس 1 (القيمة 2)\n    fmt.Println(slice) // [1 5 3 4] — الترتيب مضطرب!\n}\n
\n\n

لماذا هذا أسرع؟ لأننا لا ننسخ نصف الشريحة. نحن فقط ننقل عنصرًا واحدًا (الأخير) إلى مكان المحذوف ونختصر الشريحة. العملية من درجة O(1) مقابل O(n) في الطريقة الأولى.

\n\n

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

\n\n

الطريقة 3: الحذف حسب القيمة (أول ظهور)

\n\n

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

\n\n
func removeByValue(s []string, value string) []string {\n    for i, v := range s {\n        if v == value {\n            return append(s[:i], s[i+1:]...)\n        }\n    }\n    return s // إذا لم نجد، نعيد                

المدونات

توصيات الكتب