🔄 تكرار المصفوفات في جافا سكريبت: من الحلقة التقليدية إلى الطرق الذكية 🚀

مرحباً بك في عالم التكرارات الذكية! في هذا الدرس، سننتقل من استخدام الحلقات التقليدية for إلى تعلم مجموعة من الطرق المدمجة (Built-in Methods) في جافا سكريبت المصممة خصيصاً للتعامل مع المصفوفات. هذه الطرق تجعل الكود أنظف، أكثر قابلية للقراءة، وأسهل في الصيانة.


🎯 لماذا نحتاج إلى طرق تكرار خاصة بالمصفوفات؟

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

// مثال بالحلقة التقليدية
let fruits = ['Apple', 'Banana', 'Orange'];

for (let i = 0; i < fruits.length; i++) {
  console.log(fruits[i]);
}
// Output:
// Apple
// Banana
// Orange

✨ الطريقة forEach(): التنفيذ على كل عنصر

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

تركيبتها:

array.forEach(function(element, index, array) {
  // الكود الذي تريد تنفيذه على كل عنصر
});

مثال عملي:

let numbers = [1, 2, 3, 4, 5];
let sum = 0;

numbers.forEach(function(number) {
  sum = sum + number; // جمع كل الأرقام
});

console.log(sum); // مخرجات: 15

مثال آخر مع الفهرس:

let colors = ['Red', 'Green', 'Blue'];

colors.forEach(function(color, index) {
  console.log(`The color at index ${index} is: ${color}`);
});
// مخرجات:
// The color at index 0 is: Red
// The color at index 1 is: Green
// The color at index 2 is: Blue

🗺️ الطريقة map(): التحويل إلى مصفوفة جديدة

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

الفرق الجوهري عن forEach(): map() تُرجع مصفوفة جديدة، بينما forEach() لا تُرجع أي شيء (undefined).

تركيبتها:

let newArray = array.map(function(element, index, array) {
  return /* The new value of the element */;
});

مثال عملي: مضاعفة كل الأرقام

let originalNumbers = [2, 4, 6];

let doubledNumbers = originalNumbers.map(function(num) {
  return num * 2; // Return the value after conversion
});

console.log(originalNumbers); // Output: [2, 4, 6] (Not changed)
console.log(doubledNumbers);  // Output: [4, 8, 12] (New array)

مثال آخر: تحويل درجات الحرارة

let celsiusTemps = [0, 15, 30];
let fahrenheitTemps = celsiusTemps.map(function(celsius) {
  return (celsius * 9/5) + 32; // Convert from Celsius to Fahrenheit
});

console.log(fahrenheitTemps); // Output: [32, 59, 86]

🎭 الطريقة filter(): التصفية والترشيح

كما يوحي اسمها، وظيفة filter() هي تصفية المصفوفة وإنشاء مصفوفة جديدة تحتوي فقط على العناصر التي تجتاز اختباراً محدداً (دالة ترشيح).

مبدأ عملها: الدالة التي نمررها لـ filter() يجب أن تُرجع true إذا أردنا إبقاء العنصر، أو false إذا أردنا استبعاده.

تركيبتها:

let filteredArray = array.filter(function(element, index, array) {
  return /* condition that returns true or false */;
});

مثال عملي: تصفية الأرقام الأكبر من 10

let allNumbers = [5, 12, 8, 130, 3, 44];

let bigNumbers = allNumbers.filter(function(number) {
  return number > 10; // true for numbers > 10, false otherwise
});

console.log(bigNumbers); // Output: [12, 130, 44]

مثال آخر: البحث عن كلمات طويلة

let words = ['Swimming', 'Pen', 'Computer', 'Book', 'Programming'];

let longWords = words.filter(function(word) {
  return word.length > 4; // Select words with length greater than 4
});

console.log(longWords); // Output: ['Swimming', 'Computer', 'Programming']

📊 مقارنة سريعة بين الطرق الثلاث

الطريقة الغرض الرئيسي هل تُرجع قيمة؟ هل تغير المصفوفة الأصلية؟
forEach() تنفيذ عملية على كل عنصر. لا (undefined) لا (ما لم تعدلها بنفسك داخل الدالة).
map() تحويل كل عنصر وإنشاء مصفوفة جديدة. نعم (مصفوفة جديدة). لا.
filter() ترشيح العناصر وإنشاء مصفوفة جديدة. نعم (مصفوفة جديدة). لا.

تذكر: جميع هذه الطرق تأخذ دالة رد النداء (Callback Function) كمعطى أول. هذه الدالة تُستدعى مرة واحدة لكل عنصر في المصفوفة.


🧪 لنتمرن معاً: مثال يجمع بين الطرق

لنفترض أن لدينا مصفوفة بأعمار مجموعة من الأشخاص، ونريد الحصول على أعمارهم بعد 5 سنوات، ولكن فقط لمن هم فوق 18 سنة الآن.

let ages = [15, 22, 17, 30, 8, 45];

// 1. أولاً نرشح (نفلتر) الأعمار فوق 18 سنة.
let adults = ages.filter(function(age) {
  return age >= 18;
});
// adults الآن = [22, 30, 45]

// 2. ثم نستخدم map لإضافة 5 سنوات لكل عمر.
let agesInFiveYears = adults.map(function(age) {
  return age + 5;
});

console.log(agesInFiveYears); // Output: [27, 35, 50]