كيفية استنساخ مصفوفة في JavaScript

جافا سكريبت لديها العديد من الطرق للقيام بأي شيء. لقد كتبت على 10 طرق لكتابة الأنبوب / إنشاء في JavaScript ، ونحن الآن نقوم بعمل المصفوفات.

1. معامل الانتشار (نسخة غير عميقة)

منذ سقوط ES6 ، كانت هذه هي الطريقة الأكثر شيوعًا. إنها صيغة موجزة وستجدها مفيدة بشكل لا يصدق عند استخدام مكتبات مثل React و Redux.

numbers = [1, 2, 3]; numbersCopy = [...numbers]; 

ملاحظة: هذا لا ينسخ المصفوفات متعددة الأبعاد بأمان. يتم نسخ قيم الصفيف / الكائن حسب المرجع بدلاً من القيمة .

هذا جيد

numbersCopy.push(4); console.log(numbers, numbersCopy); // [1, 2, 3] and [1, 2, 3, 4] // numbers is left alone 

هذا ليس بخير

nestedNumbers = [[1], [2]]; numbersCopy = [...nestedNumbers]; numbersCopy[0].push(300); console.log(nestedNumbers, numbersCopy); // [[1, 300], [2]] // [[1, 300], [2]] // They've both been changed because they share references 

2. قديم جيد لـ () Loop (نسخة ضحلة)

أتخيل أن هذا النهج هو الأقل شيوعًا ، بالنظر إلى الكيفية التي أصبحت بها البرمجة الوظيفية العصرية في دوائرنا.

نقي أو نجس ، معلن أو إلزامي ، ينجز المهمة!

numbers = [1, 2, 3]; numbersCopy = []; for (i = 0; i < numbers.length; i++) { numbersCopy[i] = numbers[i]; } 

ملاحظة: هذا لا ينسخ المصفوفات متعددة الأبعاد بأمان. نظرًا لأنك تستخدم =عامل التشغيل ، فسوف يقوم بتعيين كائنات / مصفوفات حسب المرجع بدلاً من القيمة .

هذا جيد

numbersCopy.push(4); console.log(numbers, numbersCopy); // [1, 2, 3] and [1, 2, 3, 4] // numbers is left alone 

هذا ليس بخير

nestedNumbers = [[1], [2]]; numbersCopy = []; for (i = 0; i < nestedNumbers.length; i++) { numbersCopy[i] = nestedNumbers[i]; } numbersCopy[0].push(300); console.log(nestedNumbers, numbersCopy); // [[1, 300], [2]] // [[1, 300], [2]] // They've both been changed because they share references 

3. قديم جيد بينما () حلقة (نسخة ضحلة)

مثل - forالنقاء ، الواجب ، كذا ، كذا وكذا ... إنه يعمل! ؟

numbers = [1, 2, 3]; numbersCopy = []; i = -1; while (++i < numbers.length) { numbersCopy[i] = numbers[i]; } 

ملاحظة: يؤدي هذا أيضًا إلى تعيين الكائنات / المصفوفات حسب المرجع بدلاً من القيمة .

هذا جيد

numbersCopy.push(4); console.log(numbers, numbersCopy); // [1, 2, 3] and [1, 2, 3, 4] // numbers is left alone 

هذا ليس بخير

nestedNumbers = [[1], [2]]; numbersCopy = []; i = -1; while (++i < nestedNumbers.length) { numbersCopy[i] = nestedNumbers[i]; } numbersCopy[0].push(300); console.log(nestedNumbers, numbersCopy); // [[1, 300], [2]] // [[1, 300], [2]] // They've both been changed because they share references 

4. خريطة Array.map (نسخة غير عميقة)

بالعودة إلى الأراضي الحديثة ، سنجد mapالدالة. متجذر في الرياضيات ، mapهو مفهوم تحويل مجموعة إلى نوع آخر من المجموعات ، مع الحفاظ على البنية.

في اللغة الإنجليزية ، هذا يعني Array.mapإرجاع مصفوفة بنفس الطول في كل مرة.

لمضاعفة قائمة الأرقام ، استخدم mapمع doubleوظيفة.

numbers = [1, 2, 3]; double = (x) => x * 2; numbers.map(double); 

ماذا عن الاستنساخ ؟؟

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

numbers = [1, 2, 3]; numbersCopy = numbers.map((x) => x); 

إذا كنت ترغب في أن تكون رياضيًا بدرجة أكبر ، (x) => xفهذا يسمى الهوية . تقوم بإرجاع أي معلمة تم إعطاؤها لها.

map(identity) يستنسخ قائمة.

identity = (x) => x; numbers.map(identity); // [1, 2, 3] 

ملاحظة: يؤدي هذا أيضًا إلى تعيين الكائنات / المصفوفات حسب المرجع بدلاً من القيمة .

5. Array.filter (نسخة غير عميقة)

تقوم هذه الوظيفة بإرجاع مصفوفة ، تمامًا مثل map، ولكن ليس من المضمون أن تكون بنفس الطول.

ماذا لو كنت تجري تصفية للأرقام الزوجية؟

[1, 2, 3].filter((x) => x % 2 === 0); // [2] 

كان طول مصفوفة الإدخال 3 ، لكن الطول الناتج هو 1.

ومع ذلك ، إذا filterعاد المسند الخاص بك دائمًا true، فستحصل على نسخة مكررة!

numbers = [1, 2, 3]; numbersCopy = numbers.filter(() => true); 

كل عنصر يجتاز الاختبار ، لذلك يتم إرجاعه.

ملاحظة: يؤدي هذا أيضًا إلى تعيين الكائنات / المصفوفات حسب المرجع بدلاً من القيمة .

6. Array.reduce (نسخة ضحلة)

كدت أشعر بالسوء عند استخدام reduceمصفوفة ، لأنها أقوى من ذلك بكثير. لكن ها نحن ...

numbers = [1, 2, 3]; numbersCopy = numbers.reduce((newArray, element) => { newArray.push(element); return newArray; }, []); 

reduce يحول قيمة أولية أثناء حلقاتها عبر قائمة.

القيمة الأولية هنا عبارة عن مصفوفة فارغة ، ونقوم بملئها بكل عنصر كما نذهب. يجب إرجاع هذا المصفوفة من الوظيفة لاستخدامها في التكرار التالي.

ملاحظة: يؤدي هذا أيضًا إلى تعيين الكائنات / المصفوفات حسب المرجع بدلاً من القيمة .

7. Array.slice (نسخة ضحلة)

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

إذا أردنا العناصر الثلاثة الأولى:

[1, 2, 3, 4, 5].slice(0, 3); // [1, 2, 3] // Starts at index 0, stops at index 3 

If we want all the elements, don’t give any parameters

numbers = [1, 2, 3, 4, 5]; numbersCopy = numbers.slice(); // [1, 2, 3, 4, 5] 

Note: This is a shallow copy, so it also assigns objects/arrays by reference instead of by value.

8. JSON.parse and JSON.stringify (Deep copy)

JSON.stringify turns an object into a string.

JSON.parse turns a string into an object.

Combining them can turn an object into a string, and then reverse the process to create a brand new data structure.

Note: This onesafely copies deeply nested objects/arrays!

nestedNumbers = [[1], [2]]; numbersCopy = JSON.parse(JSON.stringify(nestedNumbers)); numbersCopy[0].push(300); console.log(nestedNumbers, numbersCopy); // [[1], [2]] // [[1, 300], [2]] // These two arrays are completely separate! 

9. Array.concat (Shallow copy)

concat combines arrays with values or other arrays.

[1, 2, 3].concat(4); // [1, 2, 3, 4] [1, 2, 3].concat([4, 5]); // [1, 2, 3, 4, 5] 

If you give nothing or an empty array, a shallow copy’s returned.

[1, 2, 3].concat(); // [1, 2, 3] [1, 2, 3].concat([]); // [1, 2, 3] 

Note: This also assigns objects/arrays by reference instead of by value.

10. Array.from (Shallow copy)

هذا يمكن أن يحول أي كائن قابل للتكرار إلى مصفوفة. يعطي المصفوفة نسخة ضحلة.

numbers = [1, 2, 3]; numbersCopy = Array.from(numbers); // [1, 2, 3] 

ملاحظة: يؤدي هذا أيضًا إلى تعيين الكائنات / المصفوفات حسب المرجع بدلاً من القيمة .

استنتاج

حسنًا ، كان هذا ممتعًا؟

حاولت الاستنساخ باستخدام خطوة واحدة فقط. ستجد المزيد من الطرق إذا كنت تستخدم طرقًا وتقنيات متعددة.