فيما يلي مقالة بسيطة حول بعض النصائح حول استخدام صفائف JavaScript. سنستخدم طرقًا مختلفة لدمج/دمج صفيفتين JS ، وكذلك مناقشة مزايا/عيوب كل طريقة.
لننظر في الموقف التالي أولاً:
نسخة الكود كما يلي:
var a = [1 ، 2 ، 3 ، 4 ، 5 ، 6 ، 7 ، 8 ، 9] ؛
var b = ["foo" ، "bar" ، "baz" ، "Bam" ، "Bun" ، "Fun"] ؛
من الواضح أن أبسط نتيجة مجموعة يجب أن تكون:
نسخة الكود كما يلي:
[
1 ، 2 ، 3 ، 4 ، 5 ، 6 ، 7 ، 8 ، 9 ،
"فو" ، "بار" ، "باز" ، "بام" "بون" ، "متعة"
]
Concat (..)
هذه هي الممارسة الأكثر شيوعًا:
نسخة الكود كما يلي:
var c = a.concat (b) ؛
أ ؛ // [1،2،3،4،5،6،7،8،9]
ب ؛ // ["Foo" ، "Bar" ، "Baz" ، "Bam" ، "Bun" ، "Fun"]
ج. // [1،2،3،4،5،7،8،9 ، "foo" ، "bar" ، "baz" ، "bam" ،
كما ترون ، فإن C عبارة عن صفيف جديد يمثل مزيجًا من صفيفتين A و B ويبقي A و B ثابتًا. بسيط؟
ولكن إذا كان A 10000 عنصر و B لديه 10000 عنصر؟ سيكون لـ C 20.000 عنصر ، وبالتالي فإن استخدام ذاكرة A و B سوف يتضاعف.
"لا مشكلة!" أنت قلت. دعهم يتم جمع القمامة ، وضبط A و B إلى NULL ، يتم حل المشكلة!
نسخة الكود كما يلي:
a = b = null ؛ // "A" و "B" يتم إعادة تدويرها
هيه. بالنسبة للصفائف الصغيرة مع عدد قليل من العناصر ، هذا جيد. ولكن بالنسبة للصفائف الكبيرة ، أو الأنظمة ذات الذاكرة المحدودة ، يجب تكرار هذه العملية بشكل متكرر ، فهي تحتوي بالفعل على العديد من التحسينات.
إدراج حلقة
حسنًا ، دعنا ننسخ محتويات صفيف إلى آخر ، باستخدام: Array#push (..)
نسخة الكود كما يلي:
// `b` على` a`
لـ (var i = 0 ؛ i <b.length ؛ i ++) {
A.Push (b [i]) ؛
}
أ ؛ // [1،2،3،4،5،7،8،9 ، "foo" ، "bar" ، "baz" ، "bam" ،
ب = خالية ؛
الآن ، Array A لديه محتويات Array B.
يبدو أن هناك بصمة ذاكرة أفضل.
ولكن ماذا لو كانت الصفيف أ أصغر؟ لأسباب الذاكرة والسرعة ، قد ترغب في وضع أصغر A أمام B ،. لا مشكلة ، فقط قم بتغيير الضغط (..) إلى عدم الانهيار (..):
نسخة الكود كما يلي:
// `a` في" b`:
لـ (var i = A.Length-1 ؛ i> = 0 ؛ i--) {
B.Unshift (a [i]) ؛
}
ب ؛ // [1،2،3،4،5،7،8،9 ، "foo" ، "bar" ، "baz" ، "bam" ،
المهارات الوظيفية
ومع ذلك ، فإن الحلقة من أجل القبيحة وصعبة في الواقع. هل يمكننا أن نفعل ما هو أفضل؟
هذه هي محاولتنا الأولى ، باستخدام Array#تقليل:
نسخة الكود كما يلي:
// `b` على` `:
a = b.reduce (function (coll ، item) {
coll.push (عنصر) ؛
إرجاع كول.
} ، أ) ؛
أ ؛ // [1،2،3،4،5،7،8،9 ، "foo" ، "bar" ، "baz" ، "bam" ،
// أو `a` في` b`:
B = A.REDUCERIGHT (وظيفة (coll ، البند) {
coll.unshift (item) ؛
إرجاع كول.
} ، ب) ؛
ب ؛ // [1،2،3،4،5،7،8،9 ، "foo" ، "bar" ، "baz" ، "bam" ،
صفيف#تقليل (..) و Array#التخفيض (..) لطيفة ، لكنها خرقاء بعض الشيء. ستؤدي وظيفة السهم لـ ES6 => إلى تقليل كمية التعليمات البرمجية ، لكنها لا تزال تتطلب وظيفة ، ويجب استدعاء كل عنصر مرة واحدة ، وهو أمر غير مثالي.
إذن ماذا عن هذا:
نسخة الكود كما يلي:
// `b` على` `:
A.push.apply (a ، b) ؛
أ ؛ // [1،2،3،4،5،7،8،9 ، "foo" ، "bar" ، "baz" ، "bam" ،
// أو `a` في` b`:
B.UNSHIFT.Apply (B ، A) ؛
ب ؛ // [1،2،3،4،5،7،8،9 ، "foo" ، "bar" ، "baz" ، "bam" ،
هل هذا مكان أفضل بكثير؟ خاصة وأن طريقة UNSHIFT (..) لا داعي للقلق بشأن الفرز العكسي السابق هنا. ستكون عملية الكلام في ES6 أكثر جمالًا: A.Push (... B) أو B.Unshift (...
الحد الأقصى للطول للمصفوفة
المشكلة الرئيسية الأولى هي أن زوجي استخدام الذاكرة (مؤقت فقط بالطبع!) هو نسخ العناصر في الأساس إلى المكدس عبر مكالمات الوظائف. بالإضافة إلى ذلك ، فإن محركات JS المختلفة لها قيود على طول بيانات النسخ.
لذلك ، إذا كانت الصفيف بها مليون عنصر ، فستكون بالتأكيد خارج الحد الذي يدفعه (...) أو غير مفهوم (...) يتيح مكدس الاتصال. للأسف ، ستقوم بعمل رائع في التعامل مع الآلاف من العناصر ، ولكن عليك أن تكون حريصًا على عدم تجاوز الحد المعقول للطول.
ملاحظة: يمكنك تجربة لصق (...) ، والتي لديها هذه المشكلة مثل Push (...) و Unshift (...).
هناك طريقة لتجنب هذا الحد الأقصى للطول.
نسخة الكود كما يلي:
دالة CombineInto (A ، B) {
var len = A.Length ؛
لـ (var i = 0 ؛ i <len ؛ i = i+5000) {
B.Unshift.apply (B ، A.Slice (I ، I+5000)) ؛
}
}
انتظر ، لقد ذهب قابلية القراءة إلى الوراء. هذا كل شيء ، قد يزداد سوءًا وأسوأ ، هاها.