arrays اكواد - كيف أقوم بتفريغ مصفوفة في JavaScript؟




على بالعربي (16)

هل هناك طريقة لتفريغ مصفوفة وإذا كان الأمر كذلك ، ربما مع .remove() ؟

على سبيل المثال،

A = [1,2,3,4];

كيف يمكنني تفريغ ذلك؟


Answers

لإفراغ موقع ذاكرة الحالي لصفيف استخدام: 'myArray.length = 0'أو'myArray.pop() UN-till its length is 0'

  • length: يمكنك تعيين خاصية الطول لاقتطاع مصفوفة في أي وقت. عند توسيع صفيف عن طريق تغيير الخاصية الطول ، يزيد عدد العناصر الفعلية.
  • pop(): تقوم طريقة pop بإزالة العنصر الأخير من صفيف وإرجاع ترجع القيمة التي تمت إزالتها.
  • shift(): تقوم طريقة shift بإزالة العنصر الموجود في فهرس الصفر وفصل القيم عند الفهارس المتعاقبة لأسفل ، ثم إرجاع القيمة التي تمت إزالتها.

مثال:

var arr = ['77'];
arr.length = 20;
console.log("Increasing : ", arr); // (20) ["77", empty × 19]
arr.length = 12;
console.log("Truncating : ", arr); // (12) ["77", empty × 11]

var mainArr = new Array();
mainArr = ['1', '2', '3', '4'];

var refArr = mainArr;
console.log('Current', mainArr, 'Refered', refArr);

refArr.length = 3;
console.log('Length: ~ Current', mainArr, 'Refered', refArr);

mainArr.push('0');
console.log('Push to the End of Current Array Memory Location \n~ Current', mainArr, 'Refered', refArr);

mainArr.poptill_length(0);
console.log('Empty Array \n~ Current', mainArr, 'Refered', refArr);

Array.prototype.poptill_length = function (e) {
  while (this.length) {
    if( this.length == e ) break;

    console.log('removed last element:', this.pop());
  }
};
  • Array إنشاء صفيف مع موقع ذاكرة جديد باستخدام Array constructorأو array literal.

    mainArr = []; // a new empty array is addressed to mainArr.
    
    var arr = new Array('10'); // Array constructor
    arr.unshift('1'); // add to the front
    arr.push('15'); // add to the end
    console.log("After Adding : ", arr); // ["1", "10", "15"]
    
    arr.pop(); // remove from the end
    arr.shift(); // remove from the front
    console.log("After Removing : ", arr); // ["10"]
    
    var arrLit = ['14', '17'];
    console.log("array literal « ", indexedItem( arrLit ) ); // {0,14}{1,17}
    
    function indexedItem( arr ) {
        var indexedStr = "";
        arr.forEach(function(item, index, array) {
            indexedStr += "{"+index+","+item+"}";
            console.log(item, index);
        });
        return indexedStr;
    }
    
  • slice() : باستخدام وظيفة الشريحة نحصل على نسخة ضحلة من العناصر من المصفوفة الأصلية ، مع عنوان ذاكرة جديد ، بحيث لن يؤثر أي تعديل على cloneArr على مصفوفة حقيقية |

    var shallowCopy = mainArr.slice(); // this is how to make a copy
    
    var cloneArr = mainArr.slice(0, 3); 
    console.log('Main', mainArr, '\tCloned', cloneArr);
    
    cloneArr.length = 0; // Clears current memory location of an array.
    console.log('Main', mainArr, '\tCloned', cloneArr);
    

إذا كنت تستخدم الثوابت فلا خيار أمامك:

const numbers = [1, 2, 3]

لا يمكنك إعادة تعيين:

numbers = []

يمكنك فقط اقتطاع:

numbers.length = 0

استخدم نسخة معدلة من اقتراح Jan المبدئي:

var originalLength = A.length;
for (var i = originalLength; i > 0; i--) {
     A.pop();
}

هنا أسرع تنفيذ العمل مع الحفاظ على نفس المجموعة ("mutable"):

Array.prototype.clear = function() {
  while (this.length) {
    this.pop();
  }
};

تحدد Map FYI clear() بحيث يبدو منطقيًا أن يكون لديك clear() لـ Array أيضًا.

أو كخليط Underscore.js :

_.mixin({
  clearArray: function(array) {
    while (array.length) {
      array.pop();
    }
  }
});

أو وظيفة بسيطة:

function clearArray(array) {
  while (array.length) {
    array.pop();
  }
}

إصدار TypeScript :

function clearArray<T>(array: T[]) {
  while (array.length) {
    array.pop();
  }
}

لمعلوماتك لا يمكن تبسيطها while (array.pop()) : ستفشل الاختبارات.

والاختبارات التي تتوافق معها:

describe('Array', () => {
  it('should clear the array', () => {
    let array = [1, 2, 3, 4, 5];
    array.clear();
    expect(array.length).toEqual(0);
    expect(array[0]).toEqual(undefined);
    expect(array[4]).toEqual(undefined);

    // Even with undefined or null inside
    array = [1, undefined, 3, null, 5];
    array.clear();
    expect(array.length).toEqual(0);
    expect(array[0]).toEqual(undefined);
    expect(array[4]).toEqual(undefined);
  });
});

هنا jsPerf المحدثة: http://jsperf.com/array-destroy/32 http://jsperf.com/array-destroy/152


طرق لمسح صف A موجود:

طريقة 1

(هذه كانت إجابتي الأصلية على السؤال)

A = [];

سيقوم هذا الرمز بتعيين المتغير A إلى صفيف فارغ جديد. هذا مثالي إذا لم يكن لديك إشارات إلى الصفيف الأصلي A أي مكان آخر لأن هذا في الواقع ينشئ صفيف جديد (فارغ). يجب أن تكون حذراً مع هذه الطريقة لأنه إذا قمت بالإشارة إلى هذا الصفيف من متغير آخر أو خاصية أخرى ، فسيظل المصفوفة الأصلية بدون تغيير. استخدم هذا فقط إذا قمت فقط بالرجوع إلى الصفيف من خلال متغيره الأصلي A

هذا هو أيضا الحل الأسرع.

يعرض نموذج التعليمات البرمجية هذا المشكلة التي قد تواجهها عند استخدام هذه الطريقة:

var arr1 = ['a','b','c','d','e','f'];
var arr2 = arr1;  // Reference arr1 by another variable 
arr1 = [];
console.log(arr2); // Output ['a','b','c','d','e','f']

الطريقة الثانية (كما suggested Matthew Crumley )

A.length = 0

سيؤدي هذا إلى مسح الصفيف الموجود عن طريق تعيين طوله إلى 0. وقد جادل البعض بأن هذا قد لا يعمل في جميع تطبيقات جافا سكريبت ، ولكن تبين أن الأمر ليس كذلك. كما أنه يعمل عند استخدام "الوضع المقيد" في ECMAScript 5 لأن خاصية الطول لصفيف هي خاصية القراءة / الكتابة.

الطريقة الثالثة (كما suggested Anthony )

A.splice(0,A.length)

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

الطريقة الرابعة (كما هو suggested بواسطة tanguy_k )

while(A.length > 0) {
    A.pop();
}

هذا الحل ليس مقتضبا جدا ، وهو أيضا أبطأ حل ، على عكس المعايير السابقة المشار إليها في الإجابة الأصلية.

أداء

من بين جميع أساليب مسح صفيف موجود ، تكون الطريقتان 2 و 3 متشابهة جدًا في الأداء وهي أسرع كثيرًا من الطريقة 4. انظر هذا benchmark .

كما أشار Diadistis في answer أدناه ، فإن المعايير الأصلية التي استخدمت لتحديد أداء الطرق الأربعة المذكورة أعلاه كانت معيبة. قام المعيار الأصلي بإعادة استخدام المصفوفة التي تم مسحها ، لذلك كان التكرار الثاني يقوم بمسح صفيف فارغ بالفعل.

يعمل المعيار التالي على إصلاح هذا الخطأ: benchmark . يظهر بوضوح أن الطرق # 2 (خاصية الطول) و # 3 (لصق) هي الأسرع (لا طريقة العد # 1 التي لا تغير الصفيف الأصلي).

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


سيكون الحل الأكثر ملاءمة عبر المتصفح والأكثر مثالية هو استخدام طريقة splice لإفراغ محتوى الصفيف A على النحو التالي:

A.splice(0, A.length);


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

A.length = 0;

يمكنك إضافة هذا إلى ملف JavaScript الخاص بك للسماح "بتعطيل" المصفوفات الخاصة بك:

Array.prototype.clear = function() {
    this.splice(0, this.length);
};

ثم يمكنك استخدامه على النحو التالي:

var list = [1, 2, 3];
list.clear();

أو إذا كنت تريد التأكد من أنك لا تدمر شيئًا:

if (!Array.prototype.clear) {
    Array.prototype.clear = function() {
       this.splice(0, this.length);
    };
}

يعتقد الكثير من الناس أنه لا يجب عليك تعديل الكائنات المحلية (مثل Array) ، وأنا أميل إلى الموافقة. يرجى توخي الحذر عند اتخاذ قرار بشأن كيفية التعامل مع هذا.


إذا كنت تستخدم

a = []; 

ثم تقوم بتعيين مرجع صفيف جديد إلى ، إذا تم تعيين مرجع بالفعل إلى أي متغير آخر ، فلن يؤدي ذلك إلى إفراغ هذا الصفيف أيضًا ، وبالتالي لن يجمع جامع البيانات المهملة هذه الذاكرة.

على سبيل المثال

var a=[1,2,3];
var b=a;
a=[];
console.log(b);// It will print [1,2,3];

أو

a.length = 0;

عندما نحدد a.length ، نقوم فقط بإعادة تعيين حدود الصفيف والذاكرة لربط عناصر صفيف بقية بواسطة أداة تجميع البيانات المهملة.

بدلاً من هذين المحلين أفضل.

a.splice(0,a.length)

و

while(a.length > 0) {
    a.pop();
}

حسب الإجابة السابقة بواسطة kenshou.html ، الطريقة الثانية أسرع.


الأجوبة التي لا تقل عن 2739 من الأصوات المقبولة حتى الآن هي مضللة وغير صحيحة.

السؤال هو: "كيف تفريغ صفيفك الحالي؟" مثلا ل A = [1,2,3,4] .

  1. القول " A = [] هو الجواب" هو جاهل وغير صحيح على الإطلاق. [] == [] غير صحيح .

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

لنفترض أن والدتك تطلب منك تفريغ سلة المهملات.

  • لا تجلب واحدة جديدة كما لو كنت قد فعلت ما طلب منك.
  • بدلاً من ذلك ، يمكنك إفراغ سلة المهملات.
  • أنت لا تحل محل واحد معبأ مع علبة فارغة جديدة ، وأنت لا تأخذ التسمية "A" من العلبة المعبأة والتشبث بها الجديدة كما في A = [1,2,3,4]; A = []; A = [1,2,3,4]; A = [];

إفراغ كائن المصفوفة هو أسهل شيء على الإطلاق:

A.length = 0;

بهذه الطريقة ، لا يمكن للعلامة "A" تحت عنوان "A" أن تكون فارغة فحسب ، بل أيضًا نظيفة مثل الجديدة!

  1. علاوة على ذلك ، أنت غير مطالب بإزالة القمامة باليد حتى يمكن أن تكون فارغة! تمت مطالبتك بإفراغ القائمة الحالية تمامًا في منعطف واحد ، وليس التقاط المهملات حتى تصبح فارغة ، كما هو الحال في:

    while(A.length > 0) {
        A.pop();
    }
    
  2. ولا تضع يدك اليسرى أسفل سلة المهملات ، فضعها في يمينك في الأعلى لتتمكن من سحب محتواها كما هو الحال في:

    A.splice(0, A.length);
    

لا ، لقد طُلب منك تفريغها:

A.length = 0;

هذا هو الرمز الوحيد الذي يقوم بإفراغ محتويات صفيف JavaScript محدد بشكل صحيح.


أنا مندهش لا أحد اقترح هذا حتى الآن:

let xs = [1,2,3,4];
for (let i in xs)
    delete xs[i];

هذا ينتج صفيف في حالة مختلفة تمامًا عن الحلول الأخرى. بمعنى ، تم إفراغ الصفيف:

xs
=> Array [ <4 empty slots> ]

[...xs]
=> Array [ undefined, undefined, undefined, undefined ]

xs.length
=> 4

xs[0]
=> ReferenceError: reference to undefined property xs[0]

يمكنك إنتاج صفيف مكافئ مع [,,,,] أو Array(4)


Array.prototype.clear = function() {
    this.length = 0;
};

و نسميها: array.clear();


هناك الكثير من الارتباك والتضليل فيما يتعلق بالوقت ، أداء البوب ​​/ التحول في كل من الإجابات والتعليقات. الحل أثناء / البوب ​​(كما هو متوقع) أسوأ أداء . ما يحدث في الواقع هو أن الإعداد يعمل مرة واحدة فقط لكل عينة تقوم بتشغيل المقتطف في حلقة. على سبيل المثال:

var arr = [];

for (var i = 0; i < 100; i++) { 
    arr.push(Math.random()); 
}

for (var j = 0; j < 1000; j++) {
    while (arr.length > 0) {
        arr.pop(); // this executes 100 times, not 100000
    }
}

لقد قمت بإنشاء اختبار جديد يعمل بشكل صحيح:

http://jsperf.com/empty-javascript-array-redux

تحذير: حتى في هذا الإصدار من الاختبار ، لا يمكنك رؤية الفرق الحقيقي لأن استنساخ الصفيف يستغرق معظم وقت الاختبار. لا يزال يظهر أن splice هو أسرع طريقة لمسح الصفيف (وليس أخذ [] في الاعتبار لأنه في حين أنه الأسرع فإنه لا يتم في الواقع مسح الصفيف الموجود.


استخدم أدناه إذا كنت بحاجة إلى إفراغ Angular 2+ FormArray.

public emptyFormArray(formArray:FormArray) {
    for (let i = formArray.controls.length - 1; i >= 0; i--) {
        formArray.removeAt(i);
    }
}

إذا كنت مهتمًا بتخصيص الذاكرة ، فيمكنك مقارنة كل طريقة باستخدام شيء مثل jsfiddle بالتزامن مع علامة التبويب الزمني لأدوات chrome dev. ستحتاج إلى استخدام رمز سلة المهملات في الجزء السفلي لفرض مجموعة بيانات المهملة بعد "مسح" الصفيف. يجب أن يمنحك هذا إجابة أكثر تحديدًا للمتصفح الذي تختاره. هناك الكثير من الإجابات هنا قديمة ولن أعتمد عليها ولكن بدلاً من اختبارها في الإجابة على @ tanguy_k أعلاه.

(للمقدمة إلى علامة التبويب المذكورة أعلاه يمكنك التحقق من here )

يجبرني على نسخ jsfiddle حتى هنا هو:

<html>
<script>
var size = 1000*100
window.onload = function() {
  document.getElementById("quantifier").value = size
}

function scaffold()
{
  console.log("processing Scaffold...");
  a = new Array
}
function start()
{
  size = document.getElementById("quantifier").value
  console.log("Starting... quantifier is " + size);
  console.log("starting test")
  for (i=0; i<size; i++){
    a[i]="something"
  }
  console.log("done...")
}

function tearDown()
{
  console.log("processing teardown");
  a.length=0
}

</script>
<body>
    <span style="color:green;">Quantifier:</span>
    <input id="quantifier" style="color:green;" type="text"></input>
    <button onclick="scaffold()">Scaffold</button>
    <button onclick="start()">Start</button>
    <button onclick="tearDown()">Clean</button>
    <br/>
</body>
</html>

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


نظرًا لوجود شكوى حول استخدام النموذج الأولي ، ولأن استخدام indexOf يجعل التعليمة البرمجية أقل قابلية للقراءة ، وبما أن التعبير العادي هو overkill:

function stringContains(inputString, stringToFind) {
    return (inputString.indexOf(stringToFind) != -1);
}

هذا هو الحل الوسط الذي انتهى به الأمر.







javascript arrays