من القائمة إلى الخريطة: لماذا هذا مهم وكيف تفعله بشكل صحيح؟
\n\nتخيل موقفًا: تعمل على تطبيق بلغة Kotlin، وحصلت على قائمة من المستخدمين من API. تحتاج إلى العثور بسرعة على مستخدم بواسطة معرفه. البحث في القائمة في كل مرة هو O(n)، مما يصبح ألمًا مع 1000+ عنصر. بينما البحث باستخدام Map هو O(1). الفرق هائل.
\n\nسؤال "How to convert List to Map in Kotlin?" هو أحد أكثر الأسئلة شيوعًا على Stack Overflow. وليس بدون سبب: التحويل غير الصحيح قد يؤدي إلى فقدان البيانات، أو انخفاض الأداء، أو أخطاء غريبة. اليوم سنشرح 5 طرق للتحويل، من البسيطة إلى المتقدمة، وسنعرف كيف نسرّع الكود الخاص بك 10 مرات.
\n\nالأساليب الأساسية: associate و toMap و groupBy
\n\n1. الكلاسيكية: associate - الخيار الأكثر شيوعًا
\nالدالة associate هي ملك التحويل. تأخذ لامبدا تُرجع زوجًا (مفتاح، قيمة).
data class User(val id: Int, val name: String, val age: Int)\n\nval users = listOf(\n User(1, "آنا", 25),\n User(2, "بوريس", 30),\n User(3, "فيكتور", 22)\n)\n\n// أبسط حالة: id -> name\nval idToNameMap: Map<Int, String> = users.associate { it.id to it.name }\nprintln(idToNameMap) // {1=آنا, 2=بوريس, 3=فيكتور}\n\n// الكائن الكامل حسب id\nval userMap: Map<Int, User> = users.associate { it.id to it }\nprintln(userMap[2]) // User(id=2, name="بوريس", age=30)\n\n\nهام: إذا كانت القائمة تحتوي على مفاتيح مكررة (associate ببساطة يستبدل بآخرها)، قد لا تلاحظ ذلك حتى. كن حذرًا!
2. toMap - عندما يكون لديك بالفعل مجموعة من الأزواج
\nإذا كنت قد أنشأت مسبقًا قائمة من الأزواج Pair<K, V>، استخدم toMap().
val pairs = listOf(\n 1 to "آنا",\n 2 to "بوريس",\n 3 to "فيكتور"\n)\n\nval mapFromPairs: Map<Int, String> = pairs.toMap()\nprintln(mapFromPairs) // {1=آنا, 2=بوريس, 3=فيكتور}\n\n\ntoMap تعمل أيضًا مع مجموعات Map.Entry وغيرها من مكررات الأزواج.
3. groupBy - عندما يتوافق مفتاح واحد مع عدة قيم
\nأحيانًا تحتاج إلى تجميع العناصر حسب مفتاح. على سبيل المثال، تجميع المستخدمين حسب العمر.
\n\nval usersByAge: Map<Int, List<User>> = users.groupBy { it.age }\n// النتيجة: {25=[User(id=1, name=آنا, age=25)], 30=[User(id=2, name=بوريس, age=30)], 22=[User(id=3, name=فيكتور, age=22)]}\n\n\ngroupBy تُرجع Map<K, List<V>>. مثالية للتحليلات والتصفية وإنشاء التقارير.
التقنيات المتقدمة: عندما لا تكفي الطرق القياسية
\n\n4. associateBy - إذا كنت تحتاج فقط إلى مفتاح، والقيمة هي العنصر نفسه
\nالدالة associateBy هي مرادف لـ associate { key to it }، لكنها أكثر قابلية للقراءة.
val userMapById: Map<Int, User> = users.associateBy { it.id }\n// مكافئة لـ: users.associate { it.id to it }\nprintln(userMapById[1]) // User(id=1, name=آنا, age=25)\n\n\nنصيحة: استخدم associateBy عندما تحتاج إلى إنشاء قاموس "مفتاح → الكائن نفسه". يصبح الكود أنظف.
5. تحويل مخصص مع معالجة التكرارات
\nلنفترض أن لديك قائمة من الطلبات، وقد تحتوي عدة طلبات على نفس المعرف (على سبيل المثال، إصدارات مختلفة). associate القياسي يستبدل ببساطة. ماذا لو كنت بحاجة إلى الاحتفاظ بجميعها؟
data class Order(val id: Int, val amount: Double, val version: Int)\n\nval orders = listOf(\n Order(1, 100.0, 1),\n Order(1, 150.0, 2), // معرف مكرر، لكن إصدار مختلف\n Order(2, 200.0, 1)\n)\n\n// الخيار 1: التجميع حسب المعرف\nval ordersGrouped: Map<Int, List<Order>> = orders.groupBy { it.id }\n// {1=[Order(1, 100.0, 1), Order(1, 150.0, 2)], 2=[O