كائن `Map`
تشرح هذه المقالة كائن الـ Map۔
سوف نشرح خطوة بخطوة، من العمليات الأساسية إلى أمثلة عملية مفيدة في السيناريوهات الواقعية۔
YouTube Video
كائن Map
Map هو مجموعة تخزن أزواج المفتاح والقيمة۔ إنه مشابه للكائن، ولكنه يختلف في أن أي نوع، مثل الكائنات أو الدوال أو القيم البدائية، يمكن استخدامه كمفاتيح، كما يتم الحفاظ على ترتيب الإدخال.۔
أساسيات الـ Map
أولاً، دعنا نرى كيف ننشئ كائن Map وننفذ العمليات الأساسية۔
الكود التالي هو مثال بسيط يقوم بإنشاء خريطة فارغة، ويضيف مفاتيح، ويسترجع القيم.۔
1// Create an empty Map and add key-value pairs
2const m = new Map();
3m.set('a', 1);
4m.set('b', 2);
5
6console.log(m.get('a')); // 1
7console.log(m.size); // 2
- في هذا الكود، يمكنك إضافة العناصر باستخدام
set، واسترجاع القيم باستخدامget، والتحقق من عدد العناصر باستخدامsize۔ - يحافظ كائن الـ
Mapعلى ترتيب الإدراج، مما يجعله مناسبًا للمعالجة المعتمدة على الترتيب۔
سلوك أوامر set، get، has، و delete
فيما يلي أمثلة على عمليات القراءة، الكتابة، التحقق من الوجود والحذف النموذجية۔
باستخدام الكود التالي، يمكنك التحقق من قيم الإرجاع وتأثير كل دالة۔
1// Demonstrate set, get, has, and delete
2const m2 = new Map();
3m2.set('x', 10);
4console.log(m2.has('x')); // true
5console.log(m2.get('y')); // undefined
6
7m2.delete('x');
8console.log(m2.has('x')); // false
9
10// set returns the map itself, allowing method chaining
11m2.set('a', 1).set('b', 2);
12console.log(m2); // Map { 'a' => 1, 'b' => 2 }
- تعيد
getقيمةundefinedإذا لم يكن المفتاح موجودًا۔hasيتحقق من وجود المفتاح، وdeleteيزيل المفتاح.۔ - أيضًا، لأن
setتعيد الكائن Map نفسه، فإن ربط الدوال ممكن۔
يمكن استخدام أي نوع كمفتاح (بما في ذلك استخدام الكائنات كمفاتيح)
إحدى المزايا الرئيسية لـMap هي أنه يمكنك استخدام الكائنات مباشرة كمفاتيح.۔
يُظهر المثال التالي كيفية ربط القيم في كائن Map باستخدام الكائنات كمفاتيح۔
1// Use objects as keys in a Map
2const keyObj = { id: 1 };
3const keyFunc = () => {};
4const objMap = new Map();
5
6// Another object with the same content but a different reference
7const anotherKeyObj = { id: 1 };
8
9objMap.set(keyObj, 'objectValue');
10objMap.set(keyFunc, 'functionValue');
11objMap.set(anotherKeyObj, 'anotherValue');
12
13console.log(objMap.get(keyObj)); // 'objectValue'
14console.log(objMap.get(keyFunc)); // 'functionValue'
15console.log(objMap.get(anotherKeyObj)); // 'anotherValue'
- عند استخدام الكائنات كمفاتيح، من المهم أن تكون نفس المرجع۔ حتى لو كانت محتوياتها متشابهة، الكائنات ذات المراجع المختلفة تُعتبر مختلفة وليست نفس المفتاح۔
التكرار (الحلقات)
يحافظ الـ Map على ترتيب الإدراج، لذا غالبًا ما يُستخدم في التكرار۔
فيما يلي نوضح كيفية استخدام for...of، و forEach، ودوال keys()، values()، و entries()۔
1// Iterating a Map with for...of and forEach
2const iterMap = new Map([['a', 1], ['b', 2], ['c', 3]]);
3
4// for...of over entries (default)
5for (const [key, value] of iterMap) {
6 console.log(key, value);
7}
8
9// forEach callback
10iterMap.forEach((value, key) => {
11 console.log(key, value);
12});
13
14// keys() and values()
15console.log([...iterMap.keys()]); // ['a','b','c']
16console.log([...iterMap.values()]); // [1,2,3]
- تعيد
entries()مصفوفة من أزواج[key, value]، ويمكن تحويلها إلى مصفوفة باستخدام تركيب الانتشار۔ لاحظ أن الدالة المرتجعة لـforEachتستقبل الوسيطات بالترتيب:value, key۔
التحويل بين Map و Object
يمكنك تحويل كائن موجود إلى Map، أو تحويل Map إلى كائن عادي أو مصفوفة۔
1// Convert between Map and Object / Array
2const obj = { a: 1, b: 2 };
3const mapFromObj = new Map(Object.entries(obj)); // Object -> Map
4console.log(mapFromObj.get('a')); // 1
5
6const objFromMap = Object.fromEntries(mapFromObj); // Map -> Object
7console.log(objFromMap); // { a: 1, b: 2 }
8
9const arrayFromMap = [...mapFromObj]; // Map -> Array of [key, value]
10console.log(arrayFromMap); // [['a',1], ['b',2]]
- استخدام
Object.entriesوObject.fromEntriesيسهل عملية التحويل۔ ومع ذلك، نظرًا لأن مفاتيح الكائنات تقتصر على السلاسل أو الرموز، تضيع المفاتيح غير النصية عند التحويل مرة أخرى إلى كائن۔
نمط عملي: عد التكرار (Count Map)
عند حساب تكرار العناصر في مصفوفة، يجعل استخدام Map العملية أبسط.۔
الكود التالي هو مثال على استخدام كائن Map لعد تكرارات السلاسل النصية في مصفوفة وترتيبها۔
1// Count frequencies with Map
2const arr = ['apple','banana','apple','orange','banana','apple'];
3const freq = new Map();
4
5for (const item of arr) {
6 freq.set(item, (freq.get(item) || 0) + 1);
7}
8
9console.log([...freq.entries()]); // [['apple',3], ['banana',2], ['orange',1]]
- يتيح استخدام الـ
Mapالتحقق السهل من الوجود والتحديث۔ يمكن القيام بهذا باستخدام الكائنات أيضًا، لكن الـMapقد يكون أكثر وضوحًا عند العمل مع مفاتيح عشوائية۔
ملاحظات حول Map و JSON.stringify (التسلسل)
لا يمكن لـ JSON.stringify تسلسل كائن Map مباشرة۔ إذا احتجت إلى حفظ كائن Map، يجب تحويله أولاً۔
يوضح المثال التالي كيفية تحويل Map إلى مصفوفة قبل تحويلها إلى JSON، وكيفية استرجاعها۔
1// Serialize and deserialize a Map
2const m3 = new Map([['x', 1], ['y', 2]]);
3const json = JSON.stringify([...m3]); // convert to array first
4console.log(json); // '[["x",1],["y",2]]'
5
6const restored = new Map(JSON.parse(json));
7console.log(restored.get('x')); // 1
- يجب تحويل الكائنات Map التي تحتاج للحفظ أو النقل إلى مصفوفات قبل التسلسل۔ عند الاسترجاع، استخدم
JSON.parseللتحويل إلى مصفوفة ثم أعد تحويلها إلى Map۔
مقدمة إلى WeakMap وكيفية استخدامه
يختلف WeakMap في أن مفاتيحه ذات مراجع ضعيفة (معرضة لجمع القمامة)۔
يعد مفيدًا لحفظ البيانات المؤقتة أو الفوقية باستخدام الكائنات كمفاتيح، ويتم تحريرها تلقائيًا عند جمع الكائن الرئيسي۔
1// WeakMap for metadata tied to object lifecycle
2const wm = new WeakMap();
3let obj = {};
4wm.set(obj, { meta: 'info' });
5console.log(wm.get(obj)); // { meta: 'info' }
6
7obj = null; // now the object can be GC'd and its entry removed from WeakMap
- لا يمكن تعداد عناصر الـ
WeakMapأو التحقق من حجمها، ولكنه مفيد لمنع تسرب الذاكرة۔
الملخص
Map هو مجموعة ملائمة، تسمح باستخدام أي نوع كمفتاح وتحتفظ بترتيب الإدراج على عكس الكائنات۔ من خلال فهم كل شيء من العمليات الأساسية إلى الاستخدامات المتقدمة، يمكنك إدارة البيانات بمرونة ووضوح أكبر۔ باستخدام Object و Map بشكل مناسب حسب حالة الاستخدام، يمكنك تحسين وضوح وقابلية قراءة الشيفرة بشكل كبير۔
يمكنك متابعة المقالة أعلاه باستخدام Visual Studio Code على قناتنا على YouTube.۔ يرجى التحقق من القناة على YouTube أيضًا.۔