دليل أهم دوال المصفوفات في JavaScript مع أمثلة عملية واضحة

دقائق القراءة: 9
شرح أهم دوال المصفوفات في JavaScript مع أمثلة برمجية عملية

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

في هذا الدليل، سنستعرض أشهر دوال المصفوفات في ES5 وES6+، مع توضيح الفروقات بينها، وشرح متى تستخدم كل دالة، مع أمثلة عملية تساعدك على تطبيقها مباشرة في مشاريعك.

لماذا تُعد دوال المصفوفات مهمة في JavaScript؟

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

دالة Array.forEach() للتكرار على العناصر

تُستخدم الدالة forEach() للتنفيذ على كل عنصر داخل المصفوفة مرة واحدة. وهي مناسبة عندما تريد المرور على العناصر وتنفيذ عملية مثل الطباعة أو التحديث أو الاستدعاء الجانبي، دون الحاجة إلى إرجاع مصفوفة جديدة.

صيغة الاستخدام

Array.forEach(callback(currentValue[, index[, array]])[, thisArg]);

مثال عملي

const months = ['January', 'February', 'March', 'April'];

months.forEach(function(month) {
  console.log(month);
});

/* output
January
February
March
April
*/

في هذا المثال، يتم تمرير كل عنصر تلقائياً إلى دالة callback على أنه أول وسيط.

المكافئ باستخدام حلقة for

const months = ['January', 'February', 'March', 'April'];

for (let i = 0; i < months.length; i++) {
  console.log(months[i]);
}

هل تُرجع forEach() قيمة؟

لا. الدالة forEach() لا تُرجع أي قيمة، وحتى لو كتبت return داخل دالة callback، فلن تحصل على ناتج مفيد خارجها.

const months = ['January', 'February', 'March', 'April'];

const returnedValue = months.forEach(function(month) {
  return month;
});

console.log('returnedValue:', returnedValue); // undefined

استخدام index وarray

const months = ['January', 'February', 'March', 'April'];

months.forEach(function(month, index, array) {
  console.log(month, index, array);
});

تستقبل callback ثلاث قيم مفيدة:

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

متى تستخدم forEach()؟

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

دالة Array.map() لتحويل البيانات

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

صيغة الاستخدام

Array.map(function callback(currentValue[, index[, array]]) {
  // Return element for new_array
}[, thisArg]);

مثال على تحويل النصوص إلى أحرف كبيرة

const months = ['January', 'February', 'March', 'April'];

const transformedArray = months.map(function(month) {
  return month.toUpperCase();
});

console.log(transformedArray);
// ["JANUARY", "FEBRUARY", "MARCH", "APRIL"]

المكافئ باستخدام for

const months = ['January', 'February', 'March', 'April'];
const converted = [];

for (let i = 0; i < months.length; i++) {
  converted.push(months[i].toUpperCase());
}

console.log(converted);

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

خصائص مهمة في map()

  • تُرجع مصفوفة جديدة دائماً.
  • لا تُعدّل المصفوفة الأصلية.
  • طول المصفوفة الجديدة يساوي طول المصفوفة الأصلية.

مثال على دمج خصائص الكائنات

const users = [
  { first_name: 'Mike', last_name: 'Sheridan' },
  { first_name: 'Tim', last_name: 'Lee' },
  { first_name: 'John', last_name: 'Carte' }
];

const usersList = users.map(function(user) {
  return `${user.first_name} ${user.last_name}`;
});

console.log(usersList);
// ["Mike Sheridan", "Tim Lee", "John Carte"]

استخراج حقل محدد من مصفوفة كائنات

const users = [
  { first_name: 'Mike', last_name: 'Sheridan', age: 30 },
  { first_name: 'Tim', last_name: 'Lee', age: 45 },
  { first_name: 'John', last_name: 'Carte', age: 25 }
];

const surnames = users.map(function(user) {
  return user.last_name;
});

console.log(surnames);
// ["Sheridan", "Lee", "Carte"]

إنشاء محتوى ديناميكي

const users = [
  { first_name: 'Mike', location: 'London' },
  { first_name: 'Tim', location: 'US' },
  { first_name: 'John', location: 'Australia' }
];

const usersList = users.map(function(user) {
  return `${user.first_name} lives in ${user.location}`;
});

console.log(usersList);
// ["Mike lives in London", "Tim lives in US", "John lives in Australia"]

متى تستخدم map()؟

  • عند الحاجة إلى تحويل كل عنصر إلى قيمة جديدة.
  • عند استخراج خاصية محددة من كل عنصر.
  • عند تجهيز بيانات العرض داخل الواجهات.

دالة Array.find() للعثور على أول عنصر مطابق

تُستخدم find() عندما تحتاج إلى أول عنصر يحقق شرطاً معيناً. وبمجرد العثور على أول تطابق، تتوقف الدالة عن البحث.

صيغة الاستخدام

Array.find(callback(element[, index[, array]])[, thisArg]);

مثال عملي

const employees = [
  { name: 'David Carlson', age: 30 },
  { name: 'John Cena', age: 34 },
  { name: 'Mike Sheridan', age: 25 },
  { name: 'John Carte', age: 50 }
];

const employee = employees.find(function(employee) {
  return employee.name.indexOf('John') > -1;
});

console.log(employee);
// { name: "John Cena", age: 34 }

رغم وجود John Carte في المصفوفة، ستُرجع find() أول نتيجة فقط، وهي John Cena.

أهم استخدامات find()

  • البحث عن سجل واحد داخل قائمة.
  • الوصول إلى أول عنصر يطابق شرطاً منطقياً.
  • تقليل التعقيد مقارنة بكتابة حلقة كاملة مع break.

دالة Array.findIndex() للعثور على الفهرس

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

صيغة الاستخدام

Array.findIndex(callback(element[, index[, array]])[, thisArg]);

مثال

const employees = [
  { name: 'David Carlson', age: 30 },
  { name: 'John Cena', age: 34 },
  { name: 'Mike Sheridan', age: 25 },
  { name: 'John Carte', age: 50 }
];

const index = employees.findIndex(function(employee) {
  return employee.name.indexOf('John') > -1;
});

console.log(index); // 1

إذا لم تجد الدالة أي عنصر مطابق، فإنها تُرجع -1.

متى تكون findIndex() مفيدة؟

  • عند الحاجة إلى تعديل عنصر بناءً على موقعه.
  • عند حذف عنصر من المصفوفة بعد معرفة فهرسه.
  • عند التحقق من وجود عنصر مع الحاجة إلى موقعه مباشرة.

دالة Array.filter() لاستخراج جميع العناصر المطابقة

على عكس find()، تُرجع filter() جميع العناصر التي تحقق الشرط داخل مصفوفة جديدة.

صيغة الاستخدام

Array.filter(callback(element[, index[, array]])[, thisArg]);

مثال عملي

const employees = [
  { name: 'David Carlson', age: 30 },
  { name: 'John Cena', age: 34 },
  { name: 'Mike Sheridan', age: 25 },
  { name: 'John Carte', age: 50 }
];

const employee = employees.filter(function(employee) {
  return employee.name.indexOf('John') > -1;
});

console.log(employee);
// [
//   { name: "John Cena", age: 34 },
//   { name: "John Carte", age: 50 }
// ]

الفرق بين find() وfilter()

الدالة الناتج تتوقف عند أول تطابق؟
find() عنصر واحد أو undefined نعم
filter() مصفوفة من العناصر المطابقة لا

مميزات filter()

  • تُرجع مصفوفة دائماً، حتى لو كانت فارغة.
  • ممتازة لتصفية النتائج في البحث والقوائم.
  • تُبقي المصفوفة الأصلية بدون تعديل.

دالة Array.every() للتحقق من جميع العناصر

تتحقق every() مما إذا كانت جميع العناصر داخل المصفوفة تحقق شرطاً معيناً. وتُرجع قيمة منطقية true أو false.

صيغة الاستخدام

Array.every(callback(element[, index[, array]])[, thisArg]);

مثال على التحقق من الأرقام الموجبة

let numbers = [10, -30, 20, 50];

let allPositive = numbers.every(function(number) {
  return number > 0;
});

console.log(allPositive); // false

numbers = [10, 30, 20, 50];

allPositive = numbers.every(function(number) {
  return number > 0;
});

console.log(allPositive); // true

مثال عملي في التحقق من نموذج

window.onload = function() {
  const form = document.getElementById('registration_form');

  form.addEventListener('submit', function(event) {
    event.preventDefault();

    const fields = ['first_name', 'last_name', 'email', 'city'];

    const allFieldsEntered = fields.every(function(fieldId) {
      return document.getElementById(fieldId).value.trim() !== '';
    });

    if (allFieldsEntered) {
      console.log('All the fields are entered');
    } else {
      alert('Please, fill out all the field values.');
    }
  });
};

أفضل حالات الاستخدام

  • التحقق من صحة جميع المدخلات.
  • اختبار انطباق قاعدة واحدة على كل العناصر.
  • بناء شروط جماعية مختصرة وواضحة.

دالة Array.some() للتحقق من وجود تطابق واحد على الأقل

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

صيغة الاستخدام

Array.some(callback(element[, index[, array]])[, thisArg]);

مثال على وجود عنصر موجب

let numbers = [-30, 40, 20, 50];

let containsPositive = numbers.some(function(number) {
  return number > 0;
});

console.log(containsPositive); // true

numbers = [-10, -30, -20, -50];

containsPositive = numbers.some(function(number) {
  return number > 0;
});

console.log(containsPositive); // false

مثال متقدم: التحقق من وجود موظف مع حفظ الفهرس

const employees = [
  { name: 'David Carlson', age: 30 },
  { name: 'John Cena', age: 34 },
  { name: 'Mike Sheridon', age: 25 },
  { name: 'John Carte', age: 50 }
];

let indexValue = -1;

const employee = employees.some(function(employee, index) {
  const isFound = employee.name.indexOf('John') > -1;

  if (isFound) {
    indexValue = index;
  }

  return isFound;
});

console.log(employee, indexValue); // true 1

لماذا قد تختار some()؟

  • لأنها مناسبة لاختبارات الوجود السريعة.
  • تتوقف عند أول تطابق، ما يجعلها عملية في بعض السيناريوهات.
  • يمكن استخدامها كبديل مختصر عندما تريد نتيجة منطقية فقط.

دالة Array.reduce() لتجميع القيم في ناتج واحد

تُعد reduce() من أقوى دوال المصفوفات، لأنها تسمح بتحويل مجموعة عناصر إلى قيمة واحدة نهائية. هذه القيمة قد تكون رقماً أو نصاً أو كائناً أو حتى مصفوفة جديدة، لكن النتيجة النهائية تكون قيمة واحدة فقط.

صيغة الاستخدام

Array.reduce(callback(accumulator, currentValue[, index[, array]])[, initialValue]);

مثال جمع الأرقام

const numbers = [1, 2, 3, 4, 5];

const sum = numbers.reduce(function(accumulator, number) {
  return accumulator + number;
}, 0);

console.log(sum); // 15

في هذا المثال، تبدأ قيمة accumulator من 0، ثم تتم إضافة كل عنصر إليها حتى الوصول إلى الناتج النهائي.

مثال بدون initialValue

const numbers = [1, 2, 3, 4, 5];

const sum = numbers.reduce(function(accumulator, number) {
  return accumulator + number;
});

console.log(sum); // 15

رغم أن هذا الأسلوب يعمل، فإن تحديد initialValue يظل أفضل من ناحية الوضوح وتوقع نوع البيانات الناتجة.

مثال على تعديل الناتج الابتدائي

const numbers = [1, 2, 3, 4, 5];

const doublesSum = numbers.reduce(function(accumulator, number) {
  return accumulator + number * 2;
}, 10);

console.log(doublesSum); // 40
[1 * 2, 2 * 2, 3 * 2, 4 * 2, 5 * 2] = [2, 4, 6, 8, 10]
30 + 10 = 40

مثال مع مصفوفة كائنات

const coordinates = [
  { x: 1, y: 2 },
  { x: 2, y: 3 },
  { x: 3, y: 4 }
];

const sum = coordinates.reduce(function(accumulator, currentValue) {
  return accumulator + currentValue.x;
}, 0);

console.log(sum); // 6

متى تستخدم reduce()؟

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

مقارنة سريعة بين أشهر دوال المصفوفات

الدالة الاستخدام الأساسي نوع الناتج
forEach() تنفيذ عملية على كل عنصر undefined
map() تحويل كل عنصر مصفوفة جديدة
find() العثور على أول عنصر مطابق عنصر واحد أو undefined
findIndex() العثور على فهرس أول عنصر مطابق رقم
filter() استخراج جميع العناصر المطابقة مصفوفة جديدة
every() التحقق من أن كل العناصر تحقق الشرط boolean
some() التحقق من وجود عنصر واحد يحقق الشرط boolean
reduce() تجميع العناصر في قيمة واحدة قيمة واحدة

نصائح عملية لاختيار الدالة المناسبة

  1. استخدم forEach() إذا كنت تريد تنفيذ عملية فقط دون إرجاع بيانات جديدة.
  2. استخدم map() عندما تحتاج إلى تحويل كل عنصر في المصفوفة.
  3. استخدم find() إذا كان المطلوب أول نتيجة مطابقة فقط.
  4. استخدم filter() إذا كنت تحتاج إلى جميع النتائج المطابقة.
  5. استخدم every() وsome() لبناء شروط منطقية واضحة وسريعة.
  6. استخدم reduce() عندما تريد تلخيص البيانات في مخرج واحد.

التوافق مع المتصفحات

معظم الدوال المذكورة مدعومة في المتصفحات الحديثة، لكن هناك ملاحظة مهمة: الدالتان find() وfindIndex() لا تعملان في Internet Explorer دون حلول توافقية مثل polyfill. أما forEach() وmap() وfilter() وevery() وsome() وreduce() فهي مدعومة على نطاق واسع في البيئات الحديثة والقديمة نسبياً.

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

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

اترك تعليقاً

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