شرح دالة JavaScript Map: كيفية استخدام الدالة map() في المصفوفات

دقائق القراءة: 5

ما هي الدالة map() في JavaScript؟

عند التعامل مع المصفوفات في JavaScript، ستحتاج أحياناً إلى تنفيذ عملية معينة على كل عنصر، ثم إنشاء مصفوفة جديدة تحتوي على النتائج بعد التعديل. هنا تبرز أهمية الدالة Array.map()، إذ تتيح لك المرور على عناصر المصفوفة واحداً تلو الآخر، وتطبيق دالة مخصّصة callback function على كل عنصر، ثم إرجاع مصفوفة جديدة دون تعديل المصفوفة الأصلية بشكل مباشر.

تُعد map() من أكثر دوال المصفوفات استخداماً، لأنها تمنحك أسلوباً مختصراً ومنظماً وأكثر قابلية للقراءة مقارنة باستخدام حلقات مثل for في كثير من الحالات.

شرح دالة map في JavaScript لتعديل عناصر المصفوفة وإرجاع مصفوفة جديدة

لماذا نستخدم Array.map() بدلاً من الحلقات التقليدية؟

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

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

مثال عملي: ضرب كل عنصر في رقم محدد

لنفترض أن لديك مصفوفة من الأرقام، وتريد ضرب كل عنصر في 3. يمكن تنفيذ ذلك بحلقة for، كما في المثال التالي:

let arr = [3, 4, 5, 6];

for (let i = 0; i < arr.length; i++) {
  arr[i] = arr[i] * 3;
}

console.log(arr); // [9, 12, 15, 18]

هذا الأسلوب يعمل، لكنه يغيّر المصفوفة الأصلية مباشرة. أما باستخدام map()، فيمكنك إنشاء مصفوفة جديدة بالنتائج نفسها بطريقة أكثر أناقة:

let arr = [3, 4, 5, 6];

let modifiedArr = arr.map(function (element) {
  return element * 3;
});

console.log(modifiedArr); // [9, 12, 15, 18]

في هذا المثال، تستقبل الدالة map() كل عنصر داخل المتغير element، ثم تعيد قيمة جديدة ناتجة عن ضربه في 3. وبعد انتهاء التنفيذ، تُرجع map() مصفوفة جديدة تحتوي على القيم المعدّلة.

كيف تعمل map() خطوة بخطوة؟

تمرير دالة معالجة لكل عنصر

تعتمد map() على دالة تُمرّر إليها، وتُعرف باسم callback function. هذه الدالة تُستدعى مرة واحدة لكل عنصر في المصفوفة.

إرجاع قيمة جديدة

يجب أن تُرجع دالة callback القيمة الجديدة التي تريد وضعها في المصفوفة الناتجة. إذا لم تُرجع قيمة واضحة باستخدام return، فقد تحصل على عناصر من النوع undefined.

عدم تغيير المصفوفة الأصلية

من أبرز مزايا map() أنها تعيد مصفوفة جديدة، وهذا يجعلها مناسبة عندما تريد الحفاظ على البيانات الأصلية كما هي، ثم إنتاج نسخة معدّلة منها.

استخدام map() مع مصفوفة من الكائنات

لا يقتصر استخدام map() على الأرقام فقط، بل يُستخدم كثيراً مع مصفوفات الكائنات objects، خاصة عند تجهيز البيانات للعرض أو دمج الخصائص أو استخراج جزء محدد من كل كائن.

لنفترض أن لديك مصفوفة تحتوي على أسماء أولى وأسماء أخيرة:

let users = [
  { firstName: "Susan", lastName: "Steward" },
  { firstName: "Daniel", lastName: "Longbottom" },
  { firstName: "Jacob", lastName: "Black" }
];

يمكنك استخدام map() لتجميع firstName وlastName في اسم كامل لكل مستخدم:

let users = [
  { firstName: "Susan", lastName: "Steward" },
  { firstName: "Daniel", lastName: "Longbottom" },
  { firstName: "Jacob", lastName: "Black" }
];

let userFullnames = users.map(function (element) {
  return `${element.firstName} ${element.lastName}`;
});

console.log(userFullnames);
// ["Susan Steward", "Daniel Longbottom", "Jacob Black"]

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

الصيغة الكاملة للدالة map()

الصيغة العامة لاستخدام map() تكون كالتالي:

arr.map(function (element, index, array) {
  // process element
}, thisArg);

تستقبل دالة callback عدة معاملات مهمة، وليس العنصر الحالي فقط.

المعامل element

يمثل العنصر الحالي الذي تتم معالجته داخل المصفوفة. وهذا هو المعامل الأكثر استخداماً في أغلب الحالات.

المعامل index

يمثل رقم الفهرس الحالي للعنصر داخل المصفوفة. قد تحتاج إليه إذا كانت عملية التحويل تعتمد على ترتيب العناصر.

المعامل array

يمثل المصفوفة الأصلية نفسها. يفيد ذلك عندما تريد الرجوع إلى كامل المصفوفة أثناء تنفيذ المعالجة.

المعامل thisArg

يُستخدم لتحديد قيمة this داخل دالة callback. وإذا لم يتم تمريره، تكون قيمة this افتراضياً هي undefined في كثير من السياقات.

مثال على استخدام thisArg

يمكنك تمرير قيمة مخصّصة لاستخدامها داخل callback عبر المعامل الثاني في map():

let arr = [2, 3, 5, 7];

arr.map(function (element, index, array) {
  console.log(this); // 80
}, 80);

في هذا المثال، أصبحت قيمة this داخل الدالة هي 80 لأننا مرّرناها كوسيط ثانٍ إلى map().

استكشاف جميع المعاملات التي تمررها map()

إذا أردت فهم ما الذي ترسله map() إلى الدالة في كل دورة، يمكنك تجربة المثال التالي:

let arr = [2, 3, 5, 7];

arr.map(function (element, index, array) {
  console.log(element);
  console.log(index);
  console.log(array);
  return element;
}, 80);

ستلاحظ أن الدالة تستقبل في كل مرة:

  • العنصر الحالي element.
  • فهرس العنصر index.
  • المصفوفة الأصلية array.

لكن عملياً، في معظم الاستخدامات اليومية، ستعتمد غالباً على element فقط، ولن تحتاج إلى بقية المعاملات إلا في سيناريوهات محددة.

متى تكون map() الخيار المناسب؟

استخدم map() عندما يكون هدفك الأساسي هو تحويل كل عنصر في المصفوفة إلى قيمة جديدة، مع الحفاظ على عدد العناصر نفسه في المصفوفة الناتجة.

ومن أشهر الاستخدامات العملية:

  • تحويل قائمة أرقام إلى قيم محسوبة.
  • إعادة تنسيق النصوص قبل عرضها.
  • استخراج خاصية محددة من كل كائن داخل مصفوفة.
  • إنشاء بنية بيانات جديدة انطلاقاً من بيانات موجودة.
  • تجهيز البيانات لعرضها في مكوّنات الواجهة في تطبيقات الويب.

ملاحظات مهمة عند استخدام map()

  1. يجب أن تحتوي دالة callback على return إذا كنت تريد نتائج فعلية داخل المصفوفة الجديدة.
  2. الدالة map() لا تُستخدم عادةً عندما تريد فقط تنفيذ أثر جانبي مثل الطباعة عبر console.log()؛ في هذه الحالة قد تكون forEach() أنسب.
  3. إذا كنت تريد تصفية بعض العناصر لا تحويلها، فغالباً تحتاج إلى filter() بدلاً من map().
  4. إذا كنت تريد اختزال المصفوفة إلى قيمة واحدة، فالدالة المناسبة عادة هي reduce().

صورة إضافية مرتبطة بتعلم JavaScript

غلاف كتاب لتعلم JavaScript الحديثة خطوة بخطوة للمبتدئين والمطورين

الخلاصة التقنية

تُعد الدالة Array.map() من الأدوات الأساسية في JavaScript الحديثة، لأنها تمنحك طريقة نظيفة وفعالة لتحويل عناصر المصفوفة إلى قيم جديدة دون العبث بالبيانات الأصلية. من الناحية التقنية، هي الخيار المثالي عندما تريد الحفاظ على بنية المصفوفة نفسها مع تغيير محتواها. وإذا أتقنت الفرق بينها وبين forEach() وfilter() وreduce()، فستتمكن من كتابة كود أوضح وأكثر احترافية في تطبيقاتك اليومية.

اترك تعليقاً

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