Відповіді:
Способи очищення існуючого масиву 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']
Спосіб 2 (як запропоновано від Метью Крамлі )
A.length = 0
Це очистить існуючий масив, встановивши його довжину в 0. Деякі стверджували, що це може не працювати у всіх реалізаціях JavaScript, але виявляється, що це не так. Він також працює при використанні "жорсткого режиму" в ECMAScript 5, оскільки властивість довжини масиву є властивістю читання / запису.
Спосіб 3 (як запропоновано від Anthony )
A.splice(0,A.length)
Використання .splice()
буде працювати ідеально, але оскільки .splice()
функція поверне масив із усіма видаленими елементами, він фактично поверне копію вихідного масиву. Тести свідчать, що це ніяк не впливає на продуктивність.
Спосіб 4 (як запропоновано шляхом tanguy_k )
while(A.length > 0) {
A.pop();
}
Це рішення є не дуже стислим, а також є найбільш повільним рішенням, всупереч попереднім орієнтирам, на які йдеться в оригінальній відповіді.
Продуктивність
З усіх методів очищення існуючого масиву методи 2 і 3 дуже схожі за продуктивністю і набагато швидше, ніж метод 4. Дивіться цей орієнтир .
Як вказував Діадістіс у своїй відповіді нижче, оригінальні орієнтири, які використовувались для визначення ефективності чотирьох описаних вище методів, були помилковими. Початковий орієнтир повторно використовував очищений масив, тому друга ітерація очищала масив, який вже був порожнім.
Наступний орієнтир виправляє цей недолік: http://jsben.ch/#/hyj65 . Це чітко показує, що методи №2 (властивість довжини) та №3 (сплайс) є найшвидшими (не рахуючи метод №1, який не змінює початковий масив).
Це було гарячою темою та причиною багатьох суперечок. Насправді існує багато правильних відповідей, і оскільки ця відповідь була позначена як прийнята відповідь дуже давно, я включу сюди всі методи. Якщо ви проголосуєте за цю відповідь, будь ласка, підкажіть інші відповіді, на які я також посилався.
while (A.length) { A.pop(); }
, не потрібно> 0
> 0
є більш читаним IMHO. І різниці між продуктивністю між ними немає.
b
містить посилання на старий масив навіть після того, a
як йому буде призначений новий. c
і d
продовжувати посилатися на той самий масив. Тому різниця у результатах очікується.
while(A.pop())
якщо елемент у масиві є фальсиєю. Візьмемо для прикладу A = [2, 1, 0, -1, -2] приведе до рівняння A [2, 1]. Навіть while(A.pop() !== undefined)
не працює, тому що ви можете мати масив із невизначеним як одне із значень. Можливо, тому компілятор не оптимізував це.
Якщо вам потрібно зберегти початковий масив, оскільки у вас є інші посилання на нього, які також слід оновити, ви можете очистити його, не створюючи новий масив, встановивши його довжину в нуль:
A.length = 0;
myarray.push(whatever)
він додає до довжини. Отже, встановлення довжини обрізає масив, але воно не є постійним.
length
це особлива властивість, але не лише для читання, тому вона все одно працюватиме.
Тут найшвидша реалізація , зберігаючи той самий масив ("mutable"):
function clearArray(array) {
while (array.length) {
array.pop();
}
}
FYI це не може бути спрощено while (array.pop())
: тести не вдасться.
FYI Map і Set визначають clear()
, здавалося б, логічно це мати і clear()
для Array .
Версія TypeScript:
function clearArray<T>(array: T[]) {
while (array.length) {
array.pop();
}
}
Відповідні тести:
describe('clearArray()', () => {
test('clear regular array', () => {
const array = [1, 2, 3, 4, 5];
clearArray(array);
expect(array.length).toEqual(0);
expect(array[0]).toEqual(undefined);
expect(array[4]).toEqual(undefined);
});
test('clear array that contains undefined and null', () => {
const array = [1, undefined, 3, null, 5];
clearArray(array);
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
Array.prototype
і вона робила щось дещо інше, то все в коді [].clear()
було трохи неправильним. Це не було б весело налагоджувати. Отже, загальне повідомлення: Не змінюйте глобалі.
function clear(arr) { while(arr.length) arr.pop(); }
, а потім очистіть масиви clear(arr)
замість arr.clear()
.
.splice()
і .length=0
. Тести не були правильними. Дивіться мою оновлену відповідь.
Більш зручним для веб-переглядачів і більш оптимальним рішенням буде використання splice
методу для очищення вмісту масиву A, як показано нижче:
A.splice(0, A.length);
splice
модифікує масив і повертає видалені записи. Спочатку прочитайте документи: developer.mozilla.org/en-US/docs/JavaScript/Reference/…
A.splice(0, A.length),0;
. Це дозволило б залишити значення повернення так 0
само, як A.length = 0;
і. Отриманий масив все ще створюється і повинен спричинити повільність запуску сценарію: ( jsperf ~ 56% повільніше). Реалізація браузера вплине на це, хоча я не бачу причини, чому це splice
було б швидше, ніж налаштування length
.
A.splice(0)
також працює.
Відповіді, які наразі мають не менше 2739 оновлень, є хибними та невірними.
Питання: "Як ви спорожняєте існуючий масив?" Напр A = [1,2,3,4]
.
Сказати " A = []
є відповіддю" є неосвіченим і абсолютно невірним. [] == []
є хибним .
Це тому, що ці два масиви є двома окремими, окремими об'єктами, що мають дві власні ідентичності, займаючи власний простір у цифровому світі, кожен самостійно.
Скажімо, ваша мама просить вас спорожнити сміттєвий контейнер.
A = [1,2,3,4]; A = [];
Вилучення об'єкта масиву - це найпростіша річ:
A.length = 0;
Таким чином, баночка під "А" не тільки порожня, але і така ж чиста, як нова!
Крім того, від вас не потрібно вивозити сміття вручну, доки бачка не буде порожньою! Вас попросили спорожнити існуючий повністю, за один раз, не збирати сміття до тих пір, поки контейнер не порожній, як у:
while(A.length > 0) {
A.pop();
}
Також не кладіть ліву руку в нижню частину сміття, тримаючи її правою вгорі, щоб мати змогу витягнути її вміст як у:
A.splice(0, A.length);
Ні, вас попросили спорожнити:
A.length = 0;
Це єдиний код, який правильно видаляє вміст заданого масиву JavaScript.
A(n) = A.splice( 0, A.length );
якщо вам потрібно створити резервну копію попереднього вмісту. ps Array.length
- властивість читання-запису \ метод, якщо ви пропустили цей основний факт. Значить, ви можете розширити його на нову довжину, не можете нарізати її до тієї довжини, яку хочете, і серед інших ви можете відкинути всі члени, скоротивши її довжину до 0. Це швейцарський ніж масиву.
Тест на працездатність:
http://jsperf.com/array-clear-methods/3
a = []; // 37% slower
a.length = 0; // 89% slower
a.splice(0, a.length) // 97% slower
while (a.length > 0) {
a.pop();
} // Fastest
Ви можете додати це у свій файл 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);
};
}
Багато людей думають, що ви не повинні змінювати рідні об'єкти (наприклад, масив), і я схильний погодитися. Будьте обережні, вирішуючи, як впоратися з цим.
clear
ключа?
Існує багато плутанини та дезінформації щодо часу; поп / зміна виконання як у відповідях, так і коментарях. Рішення while / pop має (як очікувалося) найгірші показники . Насправді відбувається те, що інсталяція працює лише один раз для кожного зразка, який запускає фрагмент у циклі. наприклад:
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
це найшвидший спосіб очистити масив (не враховуючи, []
оскільки, хоча це найшвидший, він фактично не очищає існуючий масив).
Якщо вас цікавить розподіл пам'яті, ви можете порівняти кожен підхід, використовуючи щось подібне до цієї jsfiddle в поєднанні з вкладкою хронологічних інструментів розробника. Ви захочете використовувати піктограму сміттєвого контейнера внизу, щоб змусити збирати сміття після 'очищення' масиву. Це має дати точнішу відповідь для обраного вами браузера. Дуже багато відповідей тут є старими, і я б на них не покладався, а скоріше перевірити, як у відповіді @ tanguy_k вище.
(для вступу до вищезгаданої вкладки ви можете ознайомитися тут )
Stackoverflow змушує мене скопіювати 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 управляє рядками інакше, ніж інші примітивні типи, не кажучи вже про масиви об’єктів. Тип може впливати на те, що відбувається.
Ви можете легко створити функцію, яка зробить це для вас, змінити довжину або навіть додати її до рідного масиву як remove()
функції для повторного використання.
Уявіть, у вас є цей масив:
var arr = [1, 2, 3, 4, 5]; //the array
Гаразд, просто запустіть це:
arr.length = 0; //change the length
і результат:
[] //result
простий спосіб спорожнити масив ...
Також використовуйте цикл, який не є необхідним, а лише іншим способом:
/* could be arr.pop() or arr.splice(0)
don't need to return as main array get changed */
function remove(arr) {
while(arr.length) {
arr.shift();
}
}
Є також складний спосіб, про який можна подумати, наприклад щось подібне:
arr.splice(0, arr.length); //[]
Отже, якщо arr має 5 елементів, вона зробить 5 елементів з 0, а це означає, що в масиві нічого не залишиться.
Також інші способи, як просто перепризначити масив, наприклад:
arr = []; //[]
Якщо ви подивитеся на функції масиву, існує багато інших способів зробити це, але найбільш рекомендованим може бути зміна довжини.
Як я вже говорив по-перше, ви також можете прототипу delete (), оскільки це відповідь на ваше запитання. ви можете просто вибрати один із способів, описаних вище, і прототипувати його для об’єкта Array в JavaScript, наприклад:
Array.prototype.remove = Array.prototype.remove || function() {
this.splice(0, this.length);
};
і ви можете просто зателефонувати так, щоб очистити будь-який масив у вашому додатку javascript:
arr.remove(); //[]
Array.prototype.clear = function() {
this.length = 0;
};
І зателефонуйте: array.clear();
A.splice(0);
Я просто зробив це за деяким кодом, над яким я працюю. Це очистило масив.
Якщо ви використовуєте
a = [];
Тоді ви призначаєте нове посилання масиву на a, якщо посилання в 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, другий метод швидший.
a.length
, я не бачу, що ця нова відповідь додає до теми?
a.length=0;
виконанні? Як би діяли ці двигуни для a.length=500;
та a.length=4;
?
var a = [1]; var b = a; a.length = 0; console.log(b)
друкує Array [ ]
, тому не здається, що це створює для мене новий масив.
Якщо ви використовуєте константи, то у вас немає вибору:
const numbers = [1, 2, 3]
Ви не можете повторно призначити:
numbers = []
Можна лише усікати:
numbers.length = 0
Для очищення поточного місця пам'яті масиву використовуйте: 'myArray.length = 0'
або'myArray.pop() UN-till its length is 0'
length
: Ви можете встановити властивість length для усічення масиву в будь-який час. Коли ви розширюєте масив, змінюючи його властивість довжини, кількість фактичних елементів збільшується.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());
}
};
new 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);
length = ?
замість просто length
.
Я здивований, що ніхто ще не запропонував цього:
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)
Використовуйте нижче, якщо вам потрібно спорожнити Angular 2+ FormArray.
public emptyFormArray(formArray:FormArray) {
for (let i = formArray.controls.length - 1; i >= 0; i--) {
formArray.removeAt(i);
}
}