Odpowiedzi:
Sposoby wyczyszczenia istniejącej tablicy A
:
Metoda 1
(to była moja pierwotna odpowiedź na pytanie)
A = [];
Ten kod ustawi zmienną A
na nową pustą tablicę. Jest to idealne rozwiązanie, jeśli nigdzie indziej nie ma odniesień do oryginalnej tablicyA
, ponieważ w rzeczywistości tworzy to zupełnie nową (pustą) tablicę. Powinieneś być ostrożny z tą metodą, ponieważ jeśli odwoływałeś się do tej tablicy z innej zmiennej lub właściwości, oryginalna tablica pozostanie niezmieniona. Używaj tego tylko, jeśli odwołujesz się do tablicy tylko przez jej oryginalną zmienną A
.
To także najszybsze rozwiązanie.
Ten przykładowy kod pokazuje problem, który możesz napotkać podczas korzystania z tej metody:
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']
Metoda 2 (jako sugerowane przez Matthew Crumley )
A.length = 0
Spowoduje to wyczyszczenie istniejącej tablicy przez ustawienie jej długości na 0. Niektórzy twierdzą, że może to nie działać we wszystkich implementacjach JavaScript, ale okazuje się, że tak nie jest. Działa również, gdy używa się „trybu ścisłego” w ECMAScript 5, ponieważ właściwość length tablicy jest właściwością odczytu / zapisu.
Metoda 3 (jako sugerowane przez Antoniego )
A.splice(0,A.length)
Używanie .splice()
będzie działać idealnie, ale ponieważ .splice()
funkcja zwróci tablicę ze wszystkimi usuniętymi elementami, faktycznie zwróci kopię oryginalnej tablicy. Testy porównawcze sugerują, że nie ma to żadnego wpływu na wydajność.
Metoda 4 (jako sugerowane przez tanguy_k )
while(A.length > 0) {
A.pop();
}
To rozwiązanie nie jest bardzo zwięzłe i jest również najwolniejszym rozwiązaniem, w przeciwieństwie do wcześniejszych testów porównawczych wymienionych w pierwotnej odpowiedzi.
Wydajność
Ze wszystkich metod czyszczenia istniejącej tablicy metody 2 i 3 są bardzo podobne pod względem wydajności i są znacznie szybsze niż metoda 4. Zobacz ten test porównawczy .
Jak zauważył Diadistis w odpowiedzi poniżej, oryginalne testy porównawcze, które zastosowano do określenia wydajności czterech opisanych powyżej metod, były wadliwe. Oryginalny test ponownie wykorzystał wyczyszczoną tablicę, więc drugą iteracją było wyczyszczenie tablicy, która była już pusta.
Poniższy test naprawia tę usterkę: http://jsben.ch/#/hyj65 . Wyraźnie pokazuje, że metody # 2 (właściwość length) i # 3 (splice) są najszybsze (nie licząc metody nr 1, która nie zmienia oryginalnej tablicy).
To był gorący temat i przyczyną wielu kontrowersji. W rzeczywistości istnieje wiele poprawnych odpowiedzi, a ponieważ odpowiedź ta była od dawna oznaczona jako odpowiedź zaakceptowana, w tym miejscu uwzględnię wszystkie metody. Jeśli głosujesz na tę odpowiedź, proszę głosować również na inne odpowiedzi, o których wspomniałem.
while (A.length) { A.pop(); }
, nie ma potrzeby> 0
> 0
jest bardziej czytelny IMHO. I nie ma między nimi żadnej różnicy wydajności.
b
zawiera odniesienie do starej tablicy nawet po a
przypisaniu nowej. c
i d
kontynuuj odwoływanie się do tej samej tablicy. Dlatego oczekuje się różnicy w wynikach.
while(A.pop())
jeśli przedmiot w tablicy jest falsey. Weźmy na przykład A = [2, 1, 0, -1, -2] dałoby A równe [2, 1]. Nawet while(A.pop() !== undefined)
nie działa, ponieważ możesz mieć tablicę z niezdefiniowaną jako jedną z wartości. Prawdopodobnie dlaczego kompilator go nie zoptymalizował.
Jeśli musisz zachować oryginalną tablicę, ponieważ masz inne odniesienia do niej, które również powinny zostać zaktualizowane, możesz ją wyczyścić bez tworzenia nowej tablicy, ustawiając jej długość na zero:
A.length = 0;
myarray.push(whatever)
dodaje jeden do długości. Tak więc ustawienie długości obcina tablicę, ale nie jest trwałe.
length
jest specjalną właściwością, ale nie tylko do odczytu, więc nadal będzie działać.
Tutaj realizacja najszybciej pracuje jednocześnie zachowując tę samą tablicę ( „zmienny”):
function clearArray(array) {
while (array.length) {
array.pop();
}
}
Dla twojej informacji nie można tego uprościć while (array.pop())
: testy zakończą się niepowodzeniem.
FYI Mapa i Set określić clear()
, byłoby to logiczne wydaje się mieć clear()
na tablicy zbyt.
Wersja TypeScript:
function clearArray<T>(array: T[]) {
while (array.length) {
array.pop();
}
}
Odpowiednie testy:
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);
});
});
Tutaj zaktualizowany jsPerf: http://jsperf.com/array-destroy/32 http://jsperf.com/array-destroy/152
Array.prototype
i robiła coś nieco innego, to cały kod [].clear()
był nieco niepoprawny. Debugowanie nie byłoby przyjemne. Zatem ogólny komunikat brzmi: Nie modyfikuj globałów.
function clear(arr) { while(arr.length) arr.pop(); }
, a następnie wyczyść tablice za pomocą clear(arr)
zamiast arr.clear()
.
.splice()
i .length=0
. Testy porównawcze były niepoprawne. Zobacz moją zaktualizowaną odpowiedź.
Bardziej przyjaznym dla różnych przeglądarek i bardziej optymalnym rozwiązaniem będzie użycie splice
metody do opróżnienia zawartości tablicy A, jak poniżej:
A.splice(0, A.length);
splice
modyfikuje tablicę i zwraca usunięte wpisy. Najpierw przeczytaj dokumentację: developer.mozilla.org/en-US/docs/JavaScript/Reference/…
A.splice(0, A.length),0;
. Pozostawiłoby to wartość zwrotną 0
tak samo jak A.length = 0;
. Powstała tablica jest nadal tworzona i powinna powodować wolniejsze działanie skryptu: ( jsperf ~ 56% wolniej). Wpłynie to na implementację przeglądarki, chociaż nie widzę powodu, dla którego splice
byłoby szybsze niż ustawienie length
.
A.splice(0)
działa.
Odpowiedzi, które mają obecnie nie mniej niż 2739 głosów pozytywnych, są mylące i niepoprawne.
Pytanie brzmi: „Jak opróżnić istniejącą tablicę?” Np A = [1,2,3,4]
. Dla .
Powiedzenie „ A = []
jest odpowiedzią” jest ignoranckie i absolutnie niepoprawne. [] == []
jest fałszywe .
Wynika to z faktu, że te dwie tablice są dwoma oddzielnymi, indywidualnymi obiektami, posiadającymi własne dwie tożsamości, zajmującymi własną przestrzeń w świecie cyfrowym, każdy z osobna.
Powiedzmy, że twoja matka prosi cię o opróżnienie kosza na śmieci.
A = [1,2,3,4]; A = [];
Opróżnianie obiektu tablicy jest najłatwiejszą rzeczą w historii:
A.length = 0;
W ten sposób puszka pod „A” jest nie tylko pusta, ale także tak czysta jak nowa!
Ponadto nie musisz ręcznie usuwać śmieci, dopóki puszka nie będzie pusta! Zostaliśmy poproszeni o opróżnienie istniejącego, całkowicie, za jednym razem, aby nie podnosić śmieci, dopóki puszka się nie opróżni, jak w:
while(A.length > 0) {
A.pop();
}
Ponadto, aby położyć lewą rękę na dole kosza, trzymając ją prawą górą, aby móc wyciągnąć jej zawartość, jak w:
A.splice(0, A.length);
Nie, poproszono Cię o opróżnienie:
A.length = 0;
Jest to jedyny kod, który poprawnie opróżnia zawartość danej tablicy JavaScript.
A(n) = A.splice( 0, A.length );
konieczność wykonania kopii zapasowej poprzedniej zawartości. ps Array.length
jest metodą odczytu / zapisu \ na wypadek, gdybyś przeoczył ten podstawowy fakt. Oznacza to, że możesz go rozszerzyć na nową długość, nie możesz przyciąć go na dowolną długość, a między innymi możesz odrzucić wszystkich członków, skracając jego długość do 0. To szwajcarski nóż z tablicy.
Test wydajności:
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
Możesz dodać to do pliku JavaScript, aby umożliwić „wyczyszczenie” tablic:
Array.prototype.clear = function() {
this.splice(0, this.length);
};
Następnie możesz użyć tego w następujący sposób:
var list = [1, 2, 3];
list.clear();
Lub jeśli chcesz mieć pewność, że czegoś nie zniszczysz:
if (!Array.prototype.clear) {
Array.prototype.clear = function() {
this.splice(0, this.length);
};
}
Wiele osób uważa, że nie powinieneś modyfikować obiektów rodzimych (takich jak Array), i jestem skłonny się zgodzić. Zachowaj ostrożność przy podejmowaniu decyzji, jak sobie z tym poradzić.
clear
klucz?
Istnieje wiele zamieszania i dezinformacji dotyczących czasu; wydajność pop / shift zarówno w odpowiedziach, jak i komentarzach. Rozwiązanie while / pop ma (zgodnie z oczekiwaniami) najgorszą wydajność . W rzeczywistości dzieje się tak, że konfiguracja jest uruchamiana tylko raz dla każdej próbki, która uruchamia fragment kodu w pętli. na przykład:
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
}
}
Utworzyłem nowy test, który działa poprawnie:
http://jsperf.com/empty-javascript-array-redux
Ostrzeżenie: nawet w tej wersji testu nie widać rzeczywistej różnicy, ponieważ klonowanie tablicy zajmuje większość czasu testu. Nadal pokazuje, że splice
jest to najszybszy sposób na wyczyszczenie tablicy (nie biorąc []
pod uwagę, ponieważ chociaż jest najszybszy, tak naprawdę nie usuwa istniejącej tablicy).
Jeśli jesteś zainteresowany alokacją pamięci, możesz porównać każde podejście, używając czegoś takiego jak ten jsfiddle w połączeniu z zakładką osi czasu chrome dev tools. Będziesz chciał użyć ikony kosza na dole, aby wymusić odśmiecanie po „wyczyszczeniu” tablicy. To powinno dać ci bardziej konkretną odpowiedź dla wybranej przeglądarki. Wiele odpowiedzi tutaj jest starych i nie chciałbym na nich polegać, a raczej przetestować, jak w powyższej odpowiedzi @ tanguy_k.
(wprowadzenie do wyżej wymienionej karty można sprawdzić tutaj )
Stackoverflow zmusza mnie do skopiowania jsfiddle, więc oto:
<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>
I należy pamiętać, że może to zależeć od typu elementów tablicy, ponieważ javascript zarządza łańcuchami inaczej niż inne typy pierwotne, nie mówiąc już o tablicach obiektów. Typ może mieć wpływ na to, co się stanie.
Możesz łatwo utworzyć funkcję, aby to zrobić, zmienić długość, a nawet dodać ją do natywnej macierzy jako remove()
funkcję do ponownego użycia.
Wyobraź sobie, że masz tę tablicę:
var arr = [1, 2, 3, 4, 5]; //the array
OK, po prostu uruchom to:
arr.length = 0; //change the length
a wynikiem jest:
[] //result
łatwy sposób na opróżnienie tablicy ...
Również za pomocą pętli, która nie jest konieczna, ale po prostu inny sposób:
/* 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();
}
}
Istnieje również trudny sposób, o którym możesz pomyśleć, na przykład coś takiego:
arr.splice(0, arr.length); //[]
Więc jeśli arr ma 5 elementów, podzieli 5 elementów od 0, co oznacza, że nic nie pozostanie w tablicy.
Również inne sposoby, takie jak po prostu przypisz tablicę, na przykład:
arr = []; //[]
Jeśli spojrzysz na funkcje macierzy, istnieje wiele innych sposobów, aby to zrobić, ale najbardziej zalecaną może być zmiana długości.
Jak już powiedziałem, możesz także prototypować remove (), ponieważ jest to odpowiedź na twoje pytanie. możesz po prostu wybrać jedną z powyższych metod i prototypować ją do obiektu Array w JavaScript, na przykład:
Array.prototype.remove = Array.prototype.remove || function() {
this.splice(0, this.length);
};
i możesz to tak nazwać, aby opróżnić dowolną tablicę w aplikacji javascript:
arr.remove(); //[]
Array.prototype.clear = function() {
this.length = 0;
};
I nazwij to: array.clear();
A.splice(0);
Właśnie to zrobiłem na pewnym kodzie, nad którym pracuję. Wyczyścił tablicę.
Jeśli używasz
a = [];
Następnie przypisujesz nowe odwołanie do tablicy, jeśli odwołanie w a jest już przypisane do jakiejkolwiek innej zmiennej, to również nie opróżni tej tablicy, a zatem śmieciarz nie zbierze tej pamięci.
Np.
var a=[1,2,3];
var b=a;
a=[];
console.log(b);// It will print [1,2,3];
lub
a.length = 0;
Kiedy określimy a.length
, po prostu resetujemy granice tablicy, a pamięć dla pozostałych elementów tablicy zostanie połączona przez moduł czyszczenia pamięci.
Zamiast tych dwóch rozwiązań są lepsze.
a.splice(0,a.length)
i
while(a.length > 0) {
a.pop();
}
Zgodnie z poprzednią odpowiedzią kenshou.html druga metoda jest szybsza.
a.length
, nie rozumiem, co ta nowa odpowiedź dodaje do wątku?
a.length=0;
wykonywania? Jak działałyby te silniki a.length=500;
i a.length=4;
?
var a = [1]; var b = a; a.length = 0; console.log(b)
drukuje Array [ ]
, więc nie wydaje mi się, że tworzy dla mnie nową tablicę.
Jeśli używasz stałych, nie masz wyboru:
const numbers = [1, 2, 3]
Nie możesz ponownie przypisać:
numbers = []
Możesz tylko obciąć:
numbers.length = 0
Aby opróżnić bieżącą lokalizację pamięci tablicy, użyj: 'myArray.length = 0'
lub'myArray.pop() UN-till its length is 0'
length
: Możesz ustawić właściwość length, aby obciąć tablicę w dowolnym momencie. Po rozszerzeniu tablicy poprzez zmianę jej właściwości długość rośnie liczba rzeczywistych elementów.pop()
: Metoda pop usuwa ostatni element z tablicy i zwraca, która zwraca usuniętą wartość.shift()
: Metoda shift usuwa element o indeksie zeroeth i przesuwa wartości przy kolejnych indeksach w dół, a następnie zwraca usuniętą wartość.Przykład:
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() | []
Utwórz tablicę z nową lokalizacją pamięci za pomocą Array constructor
lub 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()
: Używając funkcji wycinania, otrzymujemy płytką kopię elementów z oryginalnej tablicy, z nowym adresem pamięci, dzięki czemu wszelkie modyfikacje cloneArr nie wpłyną na rzeczywistą | oryginalną tablicę.
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 = ?
zamiast po prostu length
.
Dziwi mnie, że nikt jeszcze tego nie zasugerował:
let xs = [1,2,3,4];
for (let i in xs)
delete xs[i];
Daje to tablicę w zupełnie innym stanie niż inne rozwiązania. W pewnym sensie tablica została „opróżniona”:
xs
=> Array [ <4 empty slots> ]
[...xs]
=> Array [ undefined, undefined, undefined, undefined ]
xs.length
=> 4
xs[0]
=> ReferenceError: reference to undefined property xs[0]
Możesz stworzyć równoważną tablicę za pomocą [,,,,]
lubArray(4)
Użyj poniżej, jeśli chcesz opróżnić Array 2+ FormArray.
public emptyFormArray(formArray:FormArray) {
for (let i = formArray.controls.length - 1; i >= 0; i--) {
formArray.removeAt(i);
}
}