في JavaScript، يحتوي الصنف Array على طرق مدمجة قوية كثيرة لتحويل المصفوفات.
تجعل هذه الطرق تحويل مصفوفة إلى أخرى أسهل بكثير مما لو لجأنا إلى حلقة for بسيطة أو إلى تعامل مباشر مع العناصر.
بعض الطرق نقية، أي أنها لا تعدّل المصفوفة الأصلية، بل تُرجع مصفوفة جديدة بدلًا منها. أما الطرق الأخرى فتعدّل المصفوفة التي استُدعيت عليها ولا تُرجع المصفوفة المعدَّلة.
نعرض أدناه بعض الطرق الأكثر شيوعًا لتحويل المصفوفات. وتجد القائمة الكاملة بالطرق المتاحة في توثيق MDN.
map (نقية)أنشئ مصفوفة جديدة بتحويل كل عنصر وفق دالة تُمرَّر كوسيط. غالبًا ما تُكتب دوال الاستدعاء هذه على هيئة الدوال السهمية.
let arr = [1, 2, 3, 4];
const newArr = arr.map((value) => value - 1);
console.log(newArr);
// => [0, 1, 2, 3]
console.log(arr);
// => [1, 2, 3, 4]
وتجدر الإشارة إلى أن المصفوفة الناتجة ستكون دائمًا بالطول نفسه الذي للمصفوفة الأصلية.
filter (نقية)تُنشئ مصفوفة بترشيح المصفوفة الحالية وفق دالة ترشيح (تُرجع صحيحًا إذا كان ينبغي الاحتفاظ بالعنصر وخطأً إذا كان ينبغي حذفه).
let arr = [1, 2, 3, 4];
arr.filter((value) => value % 2 === 0);
// => [2, 4]
reduce (نقية)تختصر المصفوفة إلى قيمة واحدة باستخدام دالة تأخذ المُجمِّع والعنصر الحالي من المصفوفة كمعاملين. وتوضّح هذه الدالة كيفية دمج العنصر الحالي في المُجمِّع، وتُرجع المُجمِّع الذي سيُستخدم في التكرار التالي.
let arr = [1, 2, 3, 4];
// Get the sum of elements
arr.reduce((accumulator, currentValue) => accumulator + currentValue, 0);
// => 10
// Classify the numbers by whether they are odd or not
arr.reduce(
(accumulator, currentValue) => {
if (currentValue % 2 === 0) {
accumulator.even.push(currentValue);
} else {
accumulator.odd.push(currentValue);
}
return accumulator;
},
{ even: [], odd: [] },
);
// => { even: [2, 4], odd: [1, 3] }
reverseتعكس ترتيب عناصر المصفوفة.
const arr = [1, 2, 3, 4];
arr.reverse();
// => [4, 3, 2, 1]
تعدّل هذه الطريقة المصفوفة التي استُدعيت عليها.
slice (نقية)بالنظر إلى فهرس بداية وفهرس نهاية، تُنشئ مصفوفة فرعية من المصفوفة التي استُدعيت عليها.
لن يُضمَّن العنصر الواقع عند فهرس النهاية.
كما أن جميع المعاملات اختيارية:
فقيمة فهرس البداية الافتراضية 0، وقيمة فهرس النهاية الافتراضية طول المصفوفة.
const arr = [1, 2, 3, 4];
arr.slice(1, 2); // [2]
arr.slice(1); // [2, 3, 4]
// You can also use negative numbers, that represent the indexes
// starting from the end of the array
arr.slice(-2); // [3, 4]
spliceتحذف عناصر من مصفوفة أو تستبدلها، و/أو تضيف عناصر جديدة إليها. وتأخذ المعاملات التالية:
وتُرجع splice العناصر التي حُذفت.
const arr = ['1', '2', '5', '6'];
// Insert an element at index 2
arr.splice(2, 0, '3');
console.log(arr);
// => ['1', '2', '3', '5', '6']
// Remove 2 elements, starting at index 3 and insert 2 elements
const removed = arr.splice(3, 2, '4', '5');
console.log(removed);
// => ['5', '6']
console.log(arr);
// => ['1', '2', '3', '4', '5']
// Remove 1 element at index 1
arr.splice(1, 1);
console.log(arr);
// => ['1', '3', '4', '5']
sortافتراضيًا، تُرتّب sort عناصر المصفوفة بتحويلها أولًا إلى سلاسل نصية ثم بتطبيق مقارنة السلاسل النصية (انظر مفهوم المقارنة).
ويحدث الترتيب في المكان، أي أن المصفوفة الأصلية تُعدَّل.
كما تُرجع sort المصفوفة المعدَّلة نفسها، وهو أمر مريح إذا أردت ربط طرق أخرى بها.
const arr = ['c', 'a', 'z', 'b'];
const result = arr.sort();
console.log(result);
// => ['a', 'b', 'c', 'z']
console.log(arr);
// => ['a', 'b', 'c', 'z']
يؤدي هذا السلوك الافتراضي إلى نتائج خاطئة عند محاولة ترتيب الأعداد.
const arr = [3, 1, 2, 10];
arr.sort();
// => [1, 10, 2, 3]
// Because the string '10' comes before '2' in dictionary order.
لتخصيص سلوك الترتيب، يمكنك تمرير دالة مقارنة كوسيط. وتُستدعى دالة المقارنة نفسها بوسيطين هما عنصران من المصفوفة. ثم يجب أن تُرجع ما يلي:
0 إذا كان ينبغي أن يبقى ترتيب العناصر كما هووبهذا يمكن حل مشكلة ترتيب الأعداد بتمرير دالة المقارنة الصحيحة.
const arr = [3, 1, 2, 10];
arr.sort((a, b) => a - b);
// => [1, 2, 3, 10]
// "a - b" is negative when b is greater than a, positive when
// a is greater than b and 0 when they are equal.
وهذا مثال على كيفية استخدام دالة مقارنة مخصصة لترتيب مصفوفة من الكائنات.
const arr = [
{ name: 'Lydia', age: 7 },
{ name: 'Anne', age: 34 },
{ name: 'Holger', age: 59 },
];
arr.sort((item1, item2) => {
if (item1.name < item2.name) {
return -1;
}
if (item1.name > item2.name) {
return 1;
}
return 0;
});
// => [ { name: 'Anne', age: 34 }, { name: 'Holger', age: 59 },
// { name: 'Lydia', age: 7 } ]
منذ عام 2019، تنص مواصفة اللغة على أن الترتيب يجب أن يكون مستقرًا، لكن لا توجد ضمانات فيما يتعلق بالأداء (تعقيد الزمن والمساحة).