دوال (طرق) المصفوفات الأساسية (Basic Array Methods)
هذه الدوال تُستدعى على كائن المصفوفة نفسه (مثل myArray.push(...)
). بعضها يغير المصفوفة الأصلية (Mutating) وبعضها يرجع نسخة جديدة أو قيمة أخرى دون تغيير الأصل (Non-mutating).
الدوال الثابتة للكائن Array
(Static Array Methods)
- الشرح: هذه دوال تُستدعى مباشرة على المُنشئ
Array
نفسه (مثلArray.isArray()
)، وليس على مثيل مصفوفة معين (مثلmyArray.push()
). - 1-
Array.isArray(value)
:- الوظيفة: الطريقة الأكثر موثوقية للتحقق مما إذا كانت قيمة معينة هي مصفوفة بالفعل.
- القيمة المرجعة:
true
إذا كانت القيمة مصفوفة، وإلاfalse
. - لماذا هي مهمة؟ لأن
typeof []
يُرجع'object'
، مما يجعل من الصعب التمييز بين المصفوفات والكائنات العادية باستخدامtypeof
. - مثال:
console.log(Array.isArray([])); // true
console.log(Array.isArray([1, 2])); // true
console.log(Array.isArray(new Array())); // true
console.log(Array.isArray({})); // false
console.log(Array.isArray("hello")); // false
console.log(Array.isArray(null)); // false
console.log(Array.isArray(undefined)); // false
JavaScript🔸 أولًا: الإضافة إلى المصفوفة
✅ 2- push()
– لإضافة عنصر إلى نهاية المصفوفة
let fruits = ["Apple", "Banana"];
fruits.push("Mango");
console.log(fruits); // ["Apple", "Banana", "Mango"]
JavaScriptالوظيفة: تضيف عنصرًا واحدًا أو أكثر إلى نهاية المصفوفة.
تعديل الأصل: نعم.
القيمة المرجعة: الطول الجديد للمصفوفة.
let numbers = [1, 2];
let newLength = numbers.push(3, 4);
console.log(numbers); // [1, 2, 3, 4]
console.log(newLength); // 4
JavaScript✅ 3- unshift()
– لإضافة عنصر إلى بداية المصفوفة
let fruits = ["Banana", "Mango"];
fruits.unshift("Apple");
console.log(fruits); // ["Apple", "Banana", "Mango"]
JavaScriptالوظيفة: تضيف عنصرًا واحدًا أو أكثر إلى بداية المصفوفة.
تعديل الأصل: نعم.
القيمة المرجعة: الطول الجديد للمصفوفة.
مناقشة: يمكن أن تكون أبطأ من push
في المصفوفات الكبيرة لأن جميع العناصر اللاحقة تحتاج إلى إعادة فهرسة.
مثال:
let queue = ["مهمة 2", "مهمة 3"];
let newLength = queue.unshift("مهمة 1");
console.log(queue); // ["مهمة 1", "مهمة 2", "مهمة 3"]
console.log(newLength); // 3
JavaScript🔸 ثانيًا: حذف العناصر
✅ 4- pop()
– يحذف آخر عنصر في المصفوفة
الوظيفة: تزيل العنصر الأخير من المصفوفة.
تعديل الأصل: نعم.
القيمة المرجعة: العنصر الذي تمت إزالته (أو undefined
إذا كانت المصفوفة فارغة).
let fruits = ["Apple", "Banana", "Mango"];
fruits.pop();
console.log(fruits); // ["Apple", "Banana"]
---------------------------------------------
---------------------------------------------
let letters = ['a', 'b', 'c'];
let removedLetter = letters.pop();
console.log(letters); // ['a', 'b']
console.log(removedLetter); // 'c'
let emptyArr = [];
console.log(emptyArr.pop()); // undefined
JavaScript✅ 5- shift()
– يحذف أول عنصر في المصفوفة
let fruits = ["Apple", "Banana", "Mango"];
fruits.shift();
console.log(fruits); // ["Banana", "Mango"]
JavaScriptالوظيفة: تزيل العنصر الأول من المصفوفة.
تعديل الأصل: نعم.
القيمة المرجعة: العنصر الذي تمت إزالته (أو undefined
إذا كانت المصفوفة فارغة).
مناقشة: يمكن أن تكون أبطأ من pop
في المصفوفات الكبيرة لنفس سبب unshift
.
مثال:
let tasks = ["غسيل", "طبخ", "قراءة"];
let firstTask = tasks.shift();
console.log(tasks); // ["طبخ", "قراءة"]
console.log(firstTask); // "غسيل"
JavaScript🔍 جدول المراجعة:
العملية | الدالة | مكان التأثير |
---|---|---|
إضافة | push() | نهاية المصفوفة |
إضافة | unshift() | بداية المصفوفة |
حذف | pop() | نهاية المصفوفة |
حذف | shift() | بداية المصفوفة |
6- splice(startIndex, deleteCount?, item1?, ..., itemN?)
:
- الوظيفة: دالة قوية جدًا تُستخدم لتغيير محتوى مصفوفة عن طريق إزالة، استبدال، أو إضافة عناصر.
- تعديل الأصل: نعم.
- القيمة المرجعة: مصفوفة تحتوي على العناصر التي تم حذفها. إذا لم يتم حذف أي شيء، ترجع مصفوفة فارغة.
- المعاملات:
startIndex
: الفهرس الذي تبدأ منه التغييرات. يمكن أن يكون سالبًا.deleteCount
(اختياري): عدد العناصر التي سيتم حذفها بدءًا منstartIndex
.- إذا كان 0 أو محذوفًا ولم تُمرر عناصر للإضافة، فلن يتم حذف شيء.
item1, ..., itemN
(اختياري): العناصر التي سيتم إضافتها إلى المصفوفة عندstartIndex
بعد حذف العناصر (إن وجدت).
- أمثلة:
let months = ["يناير", "مارس", "أبريل", "يونيو"];
// إزالة عنصر واحد عند الفهرس 1
let removed = months.splice(1, 1);
console.log(months); // ["يناير", "أبريل", "يونيو"]
console.log(removed); // ["مارس"]
// إزالة عنصرين بدءًا من الفهرس 1 واستبدالهما
removed = months.splice(1, 2, "مايو", "يونيو المعاد");
console.log(months); // ["يناير", "مايو", "يونيو المعاد"]
console.log(removed); // ["أبريل", "يونيو"]
// إضافة عنصر عند الفهرس 1 دون حذف أي شيء
removed = months.splice(1, 0, "فبراير", "مارس", "أبريل");
console.log(months); // ["يناير", "فبراير", "مارس", "أبريل", "مايو", "يونيو المعاد"]
console.log(removed); // [] (لم يتم حذف شيء)
// إزالة عنصر واحد من النهاية
removed = months.splice(-1, 1);
console.log(months); // ["يناير", "فبراير", "مارس", "أبريل", "مايو"]
console.log(removed); // ["يونيو المعاد"]
JavaScriptSearching Array: البحث داخل المصفوفة
🔸 أهم الدوال:
الدالة | ماذا تفعل؟ |
---|---|
includes() | تتحقق إذا كانت القيمة موجودة أم لا (صح أو خطأ) |
indexOf() | تعيد الموقع (الفهرس) لأول مرة ظهرت فيه القيمة |
lastIndexOf |
✅ 7 . includes()
– هل القيمة موجودة؟
let fruits = ["Apple", "Banana", "Mango"];
console.log(fruits.includes("Banana")); // true
console.log(fruits.includes("Orange")); // false
JavaScript🟢 ترجع true أو false حسب وجود القيمة.
let pets = ["قطة", "كلب", NaN];
console.log(pets.includes("كلب")); // true
console.log(pets.includes("حصان")); // false
console.log(pets.includes("قطة", 1)); // false (البحث يبدأ من الفهرس 1)
console.log(pets.includes(NaN)); // true (تعمل مع NaN!)
JavaScript✅ 8. indexOf()
– ما هو فهرس القيمة؟ indexOf(searchElement, from Index?)
الوظيفة: تبحث عن searchElement
وتبدأ البحث من fromIndex
(اختياري، يبدأ من 0 افتراضيًا).
تعديل الأصل: لا.
القيمة المرجعة: فهرس أول ظهور للعنصر، أو -1
إذا لم يتم العثور عليه.
تستخدم المقارنة الصارمة (===
).
let names = ["Ali", "Sara", "Lina", "Ali"];
console.log(names.indexOf("Ali")); // 0 (أول ظهور لـ Ali)
console.log(names.indexOf("Lina")); // 2
console.log(names.indexOf("John")); // -1 (غير موجود)
JavaScript📌 إذا لم تكن القيمة موجودة، تعيد -1
.
مثال2:
let nums = [10, 20, 30, 20, 40];
console.log(nums.indexOf(20)); // 1 (أول ظهور)
console.log(nums.indexOf(20, 2)); // 3 (أول ظهور بدءًا من الفهرس 2)
console.log(nums.indexOf(50)); // -1 (غير موجود)
console.log(nums.indexOf("20")); // -1 (النوع مختلف)
console.log([NaN].indexOf(NaN)); // -1 (لا تعمل بشكل صحيح مع NaN)
JavaScript🔁 استخدام مع شرط (بسيط بدون if):
let colors = ["Red", "Green", "Blue"];
let color = "Green";
console.log(colors.includes(color)); // true
console.log(colors.indexOf(color)); // 1
JavaScript🔹 مثال 1: البحث في مواد دراسية
let subjects = ["Math", "English", "Physics"];
console.log(subjects.includes("Physics")); // true
console.log(subjects.indexOf("Biology")); // -1
JavaScript🔹 مثال 2: البحث في أرقام
let numbers = [10, 20, 30, 40];
console.log(numbers.includes(30)); // true
console.log(numbers.indexOf(50)); // -1
JavaScript🔹 مثال 3: التحقق قبل التنفيذ
let tools = ["Hammer", "Screwdriver", "Wrench"];
if (tools.includes("Wrench")) {
console.log("الأداة موجودة");
} else {
console.log("الأداة غير موجودة");
}
JavaScript✅ ملخص سريع:
العملية | الدالة | النتيجة |
---|---|---|
هل العنصر موجود؟ | includes() | true/false |
ما هو موقعه؟ | indexOf() | رقم الفهرس أو -1 |
9- lastIndexOf(searchElement, fromIndex?) :
الوظيفة: مشابهة لـ indexOf
، لكنها تبحث من النهاية إلى البداية.
fromIndex
(اختياري) يحدد الفهرس الذي يبدأ منه البحث للخلف (الافتراضي هو array.length - 1
). تعديل الأصل: لا.
القيمة المرجعة: فهرس آخر ظهور للعنصر، أو -1
.
مثال:
let nums = [10, 20, 30, 20, 40];
console.log(nums.lastIndexOf(20)); // 3 (آخر ظهور)
console.log(nums.lastIndexOf(20, 2)); // 1 (آخر ظهور قبل أو عند الفهرس 2)
JavaScript10- sort(compareFunction?)
:
- الوظيفة: ترتب عناصر المصفوفة في مكانها.
- تعديل الأصل: نعم.
- القيمة المرجعة: المرجع إلى المصفوفة الأصلية بعد تعديلها.
- السلوك الافتراضي (بدون
compareFunction
): تحول العناصر إلى سلاسل نصية وترتبها بناءً على قيم يونيكود (ترتيب أبجدي/معجمي). هذا يؤدي لنتائج غير متوقعة مع الأرقام! compareFunction(a, b)
(اختياري ولكن ضروري للأرقام والكائنات): دالة تأخذ عنصرين (a
,b
) وتقرر ترتيبهما:- إذا أرجعت قيمة سالبة (
< 0
):a
يأتي قبلb
. - إذا أرجعت قيمة موجبة (
> 0
):b
يأتي قبلa
. - إذا أرجعت صفرًا (
0
): الترتيب النسبي لـa
وb
لا يتغير (قد يختلف بين المتصفحات القديمة، لكنه مستقر في الحديثة).
- إذا أرجعت قيمة سالبة (
- أمثلة:
// السلوك الافتراضي (خاطئ للأرقام)
let numbers = [10, 5, 100, 1, 25];
numbers.sort();
console.log(numbers); // [1, 10, 100, 25, 5] (ترتيب كنصوص: "1", "10", "100", "25", "5")
// الترتيب الصحيح للأرقام (تصاعدي)
numbers.sort(function(a, b) {
return a - b; // إذا a<b سالب, إذا a>b موجب, إذا a=b صفر
});
// أو باستخدام دالة سهمية (Arrow Function)
// numbers.sort((a, b) => a - b);
console.log(numbers); // [1, 5, 10, 25, 100]
// الترتيب التنازلي للأرقام
numbers.sort((a, b) => b - a);
console.log(numbers); // [100, 25, 10, 5, 1]
// ترتيب السلاسل النصية (الافتراضي يعمل جيدًا للحروف الإنجليزية)
let words = ["banana", "apple", "cherry"];
words.sort();
console.log(words); // ["apple", "banana", "cherry"]
// للغة العربية، قد تحتاج لدالة localeCompare للترتيب الدقيق
let arabicWords = ["تفاح", "موز", "كرز"];
arabicWords.sort((a, b) => a.localeCompare(b, 'ar'));
console.log(arabicWords); // ["تفاح", "كرز", "موز"] (أو ترتيب آخر حسب معايير 'ar')
// ترتيب مصفوفة من الكائنات
let people = [
{ name: "علي", age: 30 },
{ name: "فاطمة", age: 25 },
{ name: "أحمد", age: 35 }
];
// الترتيب حسب العمر (تصاعدي)
people.sort((a, b) => a.age - b.age);
console.log(people);
/*
[
{ name: 'فاطمة', age: 25 },
{ name: 'علي', age: 30 },
{ name: 'أحمد', age: 35 }
]
*/
// الترتيب حسب الاسم (أبجدي)
people.sort((a, b) => a.name.localeCompare(b.name, 'ar'));
console.log(people);
/*
[
{ name: 'أحمد', age: 35 },
{ name: 'علي', age: 30 },
{ name: 'فاطمة', age: 25 }
]
*/
JavaScript11- reverse()
:
- الوظيفة: تعكس ترتيب عناصر المصفوفة في مكانها (الأول يصبح الأخير، والأخير يصبح الأول، وهكذا).
- تعديل الأصل: نعم.
- القيمة المرجعة: المرجع إلى المصفوفة الأصلية بعد تعديلها.
- مثال:
let letters = ['a', 'b', 'c'];
let reversedLetters = letters.reverse();
console.log(letters); // ['c', 'b', 'a'] (الأصل تغير)
console.log(reversedLetters); // ['c', 'b', 'a'] (نفس مرجع المصفوفة الأصلية)
JavaScript12- slice(startIndex?, endIndex?)
:
الوظيفة: تستخرج جزءًا من المصفوفة وتُرجع مصفوفة جديدة تحتوي على العناصر المحددة.
تعديل الأصل: لا.
المعاملات:
startIndex
(اختياري): الفهرس الذي تبدأ منه النسخة (مشمول). الافتراضي 0.endIndex
(اختياري): الفهرس الذي تنتهي عنده النسخة (غير مشمول).- الافتراضي هو نهاية المصفوفة.
- يمكن استخدام فهارس سالبة (تحسب من النهاية).
مناقشة: تُستخدم بشكل شائع لإنشاء نسخة سطحية (Shallow Copy) من مصفوفة أو جزء منها.
التغييرات على الكائنات أو المصفوفات المتداخلة داخل النسخة الجديدة ستؤثر على الأصل (والعكس صحيح) لأنها تشير لنفس الكائنات.
مثال:
let letters = ['a', 'b', 'c', 'd', 'e'];
let slice1 = letters.slice(1, 3); // من الفهرس 1 إلى ما قبل 3
console.log(slice1); // ['b', 'c']
console.log(letters); // ['a', 'b', 'c', 'd', 'e'] (الأصل لم يتغير)
let slice2 = letters.slice(2); // من الفهرس 2 إلى النهاية
console.log(slice2); // ['c', 'd', 'e']
let slice3 = letters.slice(-2); // آخر عنصرين
console.log(slice3); // ['d', 'e']
let shallowCopy = letters.slice(); // نسخة سطحية كاملة
console.log(shallowCopy); // ['a', 'b', 'c', 'd', 'e']
shallowCopy[0] = 'X';
console.log(letters[0]); // 'a' (الأصل لم يتأثر للعناصر البسيطة)
let nested = [1, [2, 3]];
let nestedCopy = nested.slice();
nestedCopy[1][0] = 99;
console.log(nested[1][0]); // 99 (الأصل تأثر لأن المصفوفة الداخلية نُسخت كمرجع)
JavaScriptconcat(array1?, ..., arrayN?)
:
- الوظيفة: تُستخدم لدمج مصفوفتين أو أكثر، أو إضافة قيم فردية، لإنشاء مصفوفة جديدة.
- تعديل الأصل: لا (تُرجع مصفوفة جديدة).
- المعاملات: يمكن أن تكون مصفوفات أو قيم فردية.
- إذا كان المعامل مصفوفة، يتم “تسطيح” عناصرها ودمجها (مستوى واحد فقط).
- مثال:
let arr1 = [1, 2];
let arr2 = [3, 4];
let arr3 = [7, 8];
let value = 5;
let combined1 = arr1.concat(arr2);
console.log(combined1); // [1, 2, 3, 4]
let combined2 = arr1.concat(value, arr2, 6);
console.log(combined2); // [1, 2, 5, 3, 4, 6]
let combined3 = arr1.concat(arr2, arr3);
console.log(combined3); // [1, 2, 3, 4, 7, 8]
let nestedConcat = [1].concat([2, [3, 4]]);
console.log(nestedConcat); // [1, 2, [3, 4]] (لا يتم تسطيح المصفوفات المتداخلة)
console.log(arr1); // [1, 2] (الأصل لم يتغير)
JavaScript14- join(separator?)
:
- الوظيفة: تدمج جميع عناصر المصفوفة في سلسلة نصية واحدة.
- تعديل الأصل: لا.
- القيمة المرجعة: سلسلة نصية.
- المعامل:
separator
(اختياري): السلسلة النصية التي ستُستخدم للفصل بين العناصر. الافتراضي هو الفاصلة,
. - مثال:
let parts = ["هذا", "مثال", "للانضمام"];
console.log(parts.join()); // "هذا,مثال,للانضمام" (الافتراضي)
console.log(parts.join(" ")); // "هذا مثال للانضمام"
console.log(parts.join(" - ")); // "هذا - مثال - للانضمام"
console.log([1, 2, 3].join("")); // "123"
JavaScript15- Array.prototype.flat()
📝 الوظيفة:
flat()
تُستخدم لتحويل (أو “تسطيح”) مصفوفة تحتوي على مصفوفات متداخلة إلى مصفوفة جديدة تحتوي على جميع العناصر في مستوى واحد.
array.flat(depth)
JavaScriptdepth
(اختياري): عدد المستويات التي تريد تسطيحها. القيمة الافتراضية هي 1
.
✅ أمثلة:
1. مصفوفة متداخلة بمستوى واحد:
let arr = [1, 2, [3, 4]];
let result = arr.flat();
console.log(result); // [1, 2, 3, 4]
JavaScript2. مصفوفة متداخلة بمستويين:
let deepArr = [1, 2, [3, 4, [5, 6]]];
let result1 = deepArr.flat(); // مستوى واحد فقط
console.log(result1); // [1, 2, 3, 4, [5, 6]]
let result2 = deepArr.flat(2); // مستويين
console.log(result2); // [1, 2, 3, 4, 5, 6]
JavaScript💡 الفوائد:
- تنظيم البيانات في مستوى واحد لتسهيل التعامل معها.
- مفيدة جدًا عند استخدام دوال مثل
.map()
أو عند جلب بيانات فيها تداخل. - تقلل الحاجة إلى الحلقات للتفريغ اليدوي للمصفوفات.
⚠️ ملاحظات:
flat()
لا تُغير المصفوفة الأصلية، بل تُعيد نسخة جديدة.- يجب تحديد
depth
إذا كانت المصفوفات متداخلة بأكثر من مستوى.