Réponses:
Façons d'effacer un tableau existant A
:
Méthode 1
(c'était ma réponse originale à la question)
A = [];
Ce code définira la variable A
dans un nouveau tableau vide. C'est parfait si vous n'avez aucune référence au tableau d'origineA
ailleurs car cela crée en fait un tout nouveau tableau (vide). Vous devez être prudent avec cette méthode car si vous avez référencé ce tableau à partir d'une autre variable ou propriété, le tableau d'origine restera inchangé. Utilisez-le uniquement si vous ne référencez le tableau que par sa variable d'origine A
.
C'est également la solution la plus rapide.
Cet exemple de code montre le problème que vous pouvez rencontrer lors de l'utilisation de cette méthode:
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']
Méthode 2 (comme suggéré par Matthew Crumley )
A.length = 0
Cela effacera le tableau existant en définissant sa longueur à 0. Certains ont fait valoir que cela peut ne pas fonctionner dans toutes les implémentations de JavaScript, mais il s'avère que ce n'est pas le cas. Il fonctionne également lors de l'utilisation du "mode strict" dans ECMAScript 5 car la propriété length d'un tableau est une propriété en lecture / écriture.
Méthode 3 (comme suggéré par Anthony )
A.splice(0,A.length)
L'utilisation .splice()
fonctionnera parfaitement, mais puisque la .splice()
fonction renverra un tableau avec tous les éléments supprimés, elle renverra en fait une copie du tableau d'origine. Les références suggèrent que cela n'a aucun effet sur les performances.
Méthode 4 (comme suggéré par tanguy_k )
while(A.length > 0) {
A.pop();
}
Cette solution n'est pas très succincte, et c'est aussi la solution la plus lente, contrairement aux précédents benchmarks référencés dans la réponse d'origine.
Performance
De toutes les méthodes d'effacement d'un tableau existant , les méthodes 2 et 3 sont très similaires en termes de performances et sont beaucoup plus rapides que la méthode 4. Voir ce test de performance .
Comme l'a souligné Diadistis dans sa réponse ci-dessous, les repères originaux qui ont été utilisés pour déterminer les performances des quatre méthodes décrites ci-dessus étaient défectueux. Le benchmark d'origine a réutilisé le tableau effacé de sorte que la deuxième itération effaçait un tableau qui était déjà vide.
Le benchmark suivant corrige cette faille: http://jsben.ch/#/hyj65 . Cela montre clairement que les méthodes # 2 (propriété length) et # 3 (splice) sont les plus rapides (sans compter la méthode # 1 qui ne change pas le tableau d'origine).
Cela a été un sujet brûlant et la cause de nombreuses controverses. Il y a en fait beaucoup de bonnes réponses et parce que cette réponse a été marquée comme la réponse acceptée depuis très longtemps, j'inclurai toutes les méthodes ici. Si vous votez pour cette réponse, veuillez voter également pour les autres réponses auxquelles j'ai fait référence.
while (A.length) { A.pop(); }
, pas besoin de> 0
> 0
est IMHO plus lisible. Et il n'y a aucune différence de performances entre les deux.
b
contient une référence à l'ancien tableau même après en avoir a
affecté un nouveau. c
et d
continuer à référencer le même tableau. La différence de sorties est donc attendue.
while(A.pop())
dans le cas où un élément du tableau est Falsey. Prenons par exemple A = [2, 1, 0, -1, -2] aurait pour résultat A égalant [2, 1]. Même while(A.pop() !== undefined)
ne fonctionne pas car vous pouvez avoir un tableau avec undefined comme l'une des valeurs. Probablement pourquoi le compilateur ne l'a pas optimisé.
Si vous devez conserver le tableau d'origine parce que vous y avez d'autres références qui doivent également être mises à jour, vous pouvez l'effacer sans créer de nouveau tableau en définissant sa longueur à zéro:
A.length = 0;
myarray.push(whatever)
il en ajoute un à la longueur. Ainsi, la définition de la longueur tronque le tableau, mais ce n'est pas permanent.
length
est une propriété spéciale, mais pas en lecture seule, donc cela fonctionnera toujours.
Voici l'implémentation qui fonctionne le plus rapidement tout en conservant le même tableau ("mutable"):
function clearArray(array) {
while (array.length) {
array.pop();
}
}
Pour info, il ne peut pas être simplifié while (array.pop())
: les tests échoueront.
FYI Map and Set définit clear()
, il aurait semblé logique d'avoir aussi clear()
pour Array .
Version TypeScript:
function clearArray<T>(array: T[]) {
while (array.length) {
array.pop();
}
}
Les tests correspondants:
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);
});
});
Voici le jsPerf mis à jour: http://jsperf.com/array-destroy/32 http://jsperf.com/array-destroy/152
Array.prototype
et faisait quelque chose de légèrement différent, alors tout au long de votre code [].clear()
était légèrement faux. Ce ne serait pas amusant à déboguer. Ainsi, le message général est: ne modifiez pas les globaux.
function clear(arr) { while(arr.length) arr.pop(); }
, puis effacez les tableaux avec clear(arr)
au lieu de arr.clear()
.
.splice()
et .length=0
. Les repères n'étaient pas corrects. Voir ma réponse mise à jour.
Une solution plus conviviale pour tous les navigateurs et plus optimale consiste à utiliser la splice
méthode pour vider le contenu du tableau A comme ci-dessous:
A.splice(0, A.length);
splice
modifie pas le tableau et renvoie les entrées supprimées. Lisez d'abord les documents: developer.mozilla.org/en-US/docs/JavaScript/Reference/…
A.splice(0, A.length),0;
. Cela laisserait une valeur de retour de la 0
même manière A.length = 0;
. Le tableau résultant est toujours créé et devrait ralentir l' exécution du script: ( jsperf ~ 56% plus lent). L'implémentation du navigateur affectera cela, bien que je ne vois aucune raison pour laquelle ce splice
serait plus rapide que la configuration length
.
A.splice(0)
fonctionne aussi.
Les réponses qui ont pas moins de 2739 votes positifs sont trompeuses et incorrectes.
La question est: "Comment videz-vous votre baie existante?" Par exemple pour A = [1,2,3,4]
.
Dire " A = []
est la réponse" est ignorant et absolument incorrect. [] == []
est faux .
En effet, ces deux tableaux sont deux objets distincts et individuels, avec leurs deux identités propres, occupant chacun leur propre espace dans le monde numérique.
Disons que votre mère vous demande de vider la poubelle.
A = [1,2,3,4]; A = [];
Vider un objet tableau est la chose la plus simple qui soit:
A.length = 0;
De cette façon, la boîte sous "A" est non seulement vide, mais aussi aussi propre que neuve!
De plus, vous n'êtes pas obligé de retirer la poubelle à la main jusqu'à ce que la boîte soit vide! On vous a demandé de vider l'existant, complètement, d'un seul coup, de ne pas ramasser la poubelle jusqu'à ce que la boîte soit vide, comme dans:
while(A.length > 0) {
A.pop();
}
De plus, pour mettre votre main gauche en bas de la poubelle, en la tenant avec votre droite en haut pour pouvoir extraire son contenu comme dans:
A.splice(0, A.length);
Non, on vous a demandé de le vider:
A.length = 0;
C'est le seul code qui vide correctement le contenu d'un tableau JavaScript donné.
A(n) = A.splice( 0, A.length );
cas où vous auriez besoin de sauvegarder votre contenu précédent. ps Array.length
est une propriété \ méthode en lecture-écriture au cas où vous auriez manqué ce fait de base. Cela signifie que vous pouvez l'étendre à une nouvelle longueur, vous ne pouvez pas le couper à la longueur que vous souhaitez, et entre autres, vous pouvez éliminer tous les membres en raccourcissant sa longueur à 0. C'est un couteau suisse du tableau.
Test de performance:
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
Vous pouvez l'ajouter à votre fichier JavaScript pour permettre à vos tableaux d'être "effacés":
Array.prototype.clear = function() {
this.splice(0, this.length);
};
Ensuite, vous pouvez l'utiliser comme ceci:
var list = [1, 2, 3];
list.clear();
Ou si vous voulez être sûr de ne rien détruire:
if (!Array.prototype.clear) {
Array.prototype.clear = function() {
this.splice(0, this.length);
};
}
Beaucoup de gens pensent que vous ne devriez pas modifier les objets natifs (comme Array), et je suis enclin à être d'accord. Veuillez faire preuve de prudence lorsque vous décidez comment gérer cela.
clear
clé?
Il y a beaucoup de confusion et de désinformation concernant le moment; les performances pop / shift dans les réponses et les commentaires. La solution while / pop a (comme prévu) les pires performances . Ce qui se passe réellement, c'est que le programme d'installation s'exécute une seule fois pour chaque échantillon qui exécute l'extrait de code en boucle. par exemple:
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
}
}
J'ai créé un nouveau test qui fonctionne correctement:
http://jsperf.com/empty-javascript-array-redux
Avertissement: même dans cette version du test, vous ne pouvez pas réellement voir la vraie différence car le clonage du tableau prend la plupart du temps de test. Cela montre toujours que splice
c'est le moyen le plus rapide pour effacer le tableau (sans en tenir []
compte car s'il est le plus rapide, il ne supprime pas réellement le tableau existant).
Dans le cas où vous êtes intéressé par l'allocation de mémoire, vous pouvez comparer chaque approche en utilisant quelque chose comme ce jsfiddle en conjonction avec l'onglet chronologie des outils de développement chrome. Vous voudrez utiliser l'icône de la corbeille en bas pour forcer une collecte des ordures après avoir `` effacé '' le tableau. Cela devrait vous donner une réponse plus précise pour le navigateur de votre choix. Beaucoup de réponses ici sont anciennes et je ne m'appuierais pas sur elles mais plutôt tester comme dans la réponse de @ tanguy_k ci-dessus.
(pour une introduction à l'onglet susmentionné, vous pouvez consulter ici )
Stackoverflow m'oblige à copier le jsfiddle alors le voici:
<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>
Et vous devez prendre note que cela peut dépendre du type des éléments du tableau, car javascript gère les chaînes différemment des autres types primitifs, sans parler des tableaux d'objets. Le type peut affecter ce qui se passe.
Vous pouvez facilement créer une fonction pour le faire pour vous, changer la longueur ou même l'ajouter à la matrice native comme remove()
fonction à réutiliser.
Imaginez que vous ayez ce tableau:
var arr = [1, 2, 3, 4, 5]; //the array
OK, lancez simplement ceci:
arr.length = 0; //change the length
et le résultat est:
[] //result
moyen facile de vider un tableau ...
Utiliser également une boucle qui n'est pas nécessaire mais juste une autre façon de le faire:
/* 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();
}
}
Il existe également des moyens délicats auxquels vous pouvez penser, par exemple quelque chose comme ceci:
arr.splice(0, arr.length); //[]
Donc, si arr a 5 éléments, il séparera 5 éléments de 0, ce qui signifie que rien ne restera dans le tableau.
D'autres façons, comme simplement réaffecter le tableau par exemple:
arr = []; //[]
Si vous regardez les fonctions du tableau, il existe de nombreuses autres façons de le faire, mais la plus recommandée pourrait être de changer la longueur.
Comme je l'ai dit en premier lieu, vous pouvez également supprimer prototype () car c'est la réponse à votre question. vous pouvez simplement choisir l'une des méthodes ci-dessus et la prototyper en objet Array en JavaScript, quelque chose comme:
Array.prototype.remove = Array.prototype.remove || function() {
this.splice(0, this.length);
};
et vous pouvez simplement l'appeler comme ceci pour vider n'importe quel tableau dans votre application javascript:
arr.remove(); //[]
Array.prototype.clear = function() {
this.length = 0;
};
Et appelez ça: array.clear();
A.splice(0);
Je viens de le faire sur un code sur lequel je travaille. Il a effacé le tableau.
Si vous utilisez
a = [];
Ensuite, vous affectez une nouvelle référence de tableau à a, si la référence dans a est déjà affectée à une autre variable, il ne videra pas ce tableau aussi et donc le garbage collector ne collectera pas cette mémoire.
Par exemple.
var a=[1,2,3];
var b=a;
a=[];
console.log(b);// It will print [1,2,3];
ou
a.length = 0;
Lorsque nous spécifions a.length
, nous ne faisons que réinitialiser les limites du tableau et la mémoire pour les éléments du tableau reste sera connectée par le garbage collector.
Au lieu de ces deux solutions, c'est mieux.
a.splice(0,a.length)
et
while(a.length > 0) {
a.pop();
}
Selon la réponse précédente de kenshou.html, la deuxième méthode est plus rapide.
a.length
, je ne vois pas ce que cette nouvelle réponse ajoute au fil?
a.length=0;
exécuté? Comment ces moteurs agiraient-ils pour a.length=500;
et a.length=4;
?
var a = [1]; var b = a; a.length = 0; console.log(b)
imprime Array [ ]
, donc il ne semble pas que cela crée un nouveau tableau pour moi.
Si vous utilisez des constantes, vous n'avez pas le choix:
const numbers = [1, 2, 3]
Vous ne pouvez pas reconcevoir:
numbers = []
Vous ne pouvez tronquer que:
numbers.length = 0
Pour vider un emplacement de mémoire actuel d'une baie, utilisez: 'myArray.length = 0'
ou'myArray.pop() UN-till its length is 0'
length
: Vous pouvez définir la propriété length pour tronquer un tableau à tout moment. Lorsque vous étendez un tableau en modifiant sa propriété length, le nombre d'éléments réels augmente.pop()
: La méthode pop supprime le dernier élément d'un tableau et retourne qui renvoie la valeur supprimée.shift()
: La méthode de décalage supprime l'élément au zéro index et décale les valeurs d'index consécutifs vers le bas, puis renvoie la valeur supprimée.Exemple:
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() | []
Créez un tableau avec un nouvel emplacement mémoire en utilisant Array constructor
ou 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()
: En utilisant la fonction slice, nous obtenons une copie superficielle des éléments du tableau d'origine, avec une nouvelle adresse mémoire, de sorte que toute modification sur cloneArr n'affectera pas un tableau | original réel.
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 = ?
au lieu de juste length
.
Je suis surpris que personne ne l'ait encore suggéré:
let xs = [1,2,3,4];
for (let i in xs)
delete xs[i];
Cela donne un tableau dans un état assez différent des autres solutions. Dans un sens, le tableau a été «vidé»:
xs
=> Array [ <4 empty slots> ]
[...xs]
=> Array [ undefined, undefined, undefined, undefined ]
xs.length
=> 4
xs[0]
=> ReferenceError: reference to undefined property xs[0]
Vous pouvez produire un tableau équivalent avec [,,,,]
ouArray(4)
Utilisez ci-dessous si vous devez vider Angular 2+ FormArray.
public emptyFormArray(formArray:FormArray) {
for (let i = formArray.controls.length - 1; i >= 0; i--) {
formArray.removeAt(i);
}
}