Respostas:
Maneiras de limpar uma matriz existente A
:
Método 1
(esta foi minha resposta original à pergunta)
A = [];
Este código definirá a variável A
para uma nova matriz vazia. Isso é perfeito se você não tiver referências à matriz original emA
nenhum outro lugar, porque isso realmente cria uma nova matriz (vazia). Você deve ter cuidado com esse método, porque se você referenciou essa matriz de outra variável ou propriedade, a matriz original permanecerá inalterada. Use isso somente se você fizer referência à matriz por sua variável original A
.
Essa também é a solução mais rápida.
Este exemplo de código mostra o problema que você pode encontrar ao usar este método:
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étodo 2 (conforme sugerido por Matthew Crumley )
A.length = 0
Isso limpará a matriz existente, definindo seu comprimento como 0. Alguns argumentaram que isso pode não funcionar em todas as implementações de JavaScript, mas acontece que esse não é o caso. Também funciona ao usar o "modo estrito" no ECMAScript 5 porque a propriedade length de uma matriz é uma propriedade de leitura / gravação.
Método 3 (como sugerido por Anthony )
A.splice(0,A.length)
O uso .splice()
funcionará perfeitamente, mas como o.splice()
função retornará uma matriz com todos os itens removidos, ela realmente retornará uma cópia da matriz original. Os benchmarks sugerem que isso não afeta o desempenho.
Método 4 (conforme sugerido por tanguy_k )
while(A.length > 0) {
A.pop();
}
Essa solução não é muito sucinta e também é a solução mais lenta, ao contrário dos benchmarks anteriores mencionados na resposta original.
atuação
De todos os métodos de limpeza de uma matriz existente , os métodos 2 e 3 são muito semelhantes no desempenho e são muito mais rápidos que o método 4. Consulte este benchmark .
Como apontado por Diadistis em sua resposta abaixo, os benchmarks originais que foram usados para determinar o desempenho dos quatro métodos descritos acima foram falhos. O benchmark original reutilizou a matriz limpa, portanto a segunda iteração estava limpando uma matriz que já estava vazia.
O seguinte benchmark corrige essa falha: http://jsben.ch/#/hyj65 . Isso mostra claramente que os métodos nº 2 (propriedade length) e nº 3 (emenda) são os mais rápidos (sem contar o método nº 1, que não altera a matriz original).
Este tem sido um tópico quente e a causa de muita controvérsia. Na verdade, existem muitas respostas corretas e, como essa resposta foi marcada como resposta aceita por muito tempo, incluirei todos os métodos aqui. Se você votar nesta resposta, faça um voto positivo nas outras respostas que eu referenciei também.
while (A.length) { A.pop(); }
, não há necessidade de> 0
> 0
é IMHO mais legível. E não há diferença de desempenho entre os dois.
b
mantém uma referência à matriz antiga mesmo após a a
atribuição de uma nova. c
e d
continue a referenciar a mesma matriz. A diferença nas saídas é, portanto, esperada.
while(A.pop())
caso um item na matriz seja falsey. Tomemos, por exemplo, A = [2, 1, 0, -1, -2] resultaria em A igual a [2, 1]. Mesmo while(A.pop() !== undefined)
não funciona porque você pode ter uma matriz com indefinido como um dos valores. Provavelmente porque o compilador não o otimizou.
Se você precisar manter a matriz original porque também possui outras referências que também devem ser atualizadas, limpe-a sem criar uma nova matriz, definindo seu comprimento como zero:
A.length = 0;
myarray.push(whatever)
, adiciona uma ao comprimento. Portanto, definir o comprimento trunca a matriz, mas não é permanente.
length
é uma propriedade especial, mas não é somente de leitura, por isso ainda funcionará.
Aqui está a implementação de trabalho mais rápida , mantendo a mesma matriz ("mutável"):
function clearArray(array) {
while (array.length) {
array.pop();
}
}
Para sua informação, não pode ser simplificado while (array.pop())
: os testes falharão.
Mapa e conjunto da FYI define clear()
, parece lógico ter clear()
para Array .
Versão TypeScript:
function clearArray<T>(array: T[]) {
while (array.length) {
array.pop();
}
}
Os testes correspondentes:
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);
});
});
Aqui o jsPerf atualizado: http://jsperf.com/array-destroy/32 http://jsperf.com/array-destroy/152
Array.prototype
e estava fazendo algo um pouco diferente, então todo o seu código [].clear()
estava um pouco errado. Isso não seria divertido de depurar. Portanto, a mensagem geral é: não modifique globais.
function clear(arr) { while(arr.length) arr.pop(); }
e limpe os arrays com em clear(arr)
vez de arr.clear()
.
.splice()
e .length=0
. Os benchmarks não estavam corretos. Veja minha resposta atualizada.
Uma solução mais otimizada para vários navegadores e mais otimizada será usar o splice
método para esvaziar o conteúdo da matriz A, conforme abaixo:
A.splice(0, A.length);
splice
modifica a matriz e retorna as entradas excluídas. Leia os documentos primeiro: developer.mozilla.org/en-US/docs/JavaScript/Reference/…
A.splice(0, A.length),0;
. Isso deixaria um valor de retorno 0
exatamente como A.length = 0;
faria. A matriz resultante ainda é criada e deve fazer com que o script seja executado mais lentamente: ( jsperf ~ 56% mais lento). A implementação do navegador afetará isso, embora não haja razão para splice
que seja mais rápido que a configuração length
.
A.splice(0)
também funciona.
As respostas que não têm menos que 2739 votos até agora são enganosas e incorretas.
A pergunta é: "Como você esvazia sua matriz existente?" Por exemplo, para A = [1,2,3,4]
.
Dizer " A = []
é a resposta" é ignorante e absolutamente incorreto. [] == []
é falso .
Isso ocorre porque essas duas matrizes são dois objetos individuais separados, com suas próprias duas identidades, ocupando seu próprio espaço no mundo digital, cada um por si.
Digamos que sua mãe pede que você esvazie a lata de lixo.
A = [1,2,3,4]; A = [];
Esvaziar um objeto de matriz é a coisa mais fácil de sempre:
A.length = 0;
Dessa forma, a lata em "A" não está apenas vazia, mas também limpa como nova!
Além disso, você não precisa remover o lixo manualmente até que a lata esteja vazia! Você foi solicitado a esvaziar completamente o existente, em um turno, para não recolher o lixo até que a lata fique vazia, como em:
while(A.length > 0) {
A.pop();
}
Além disso, para colocar a mão esquerda na parte inferior do lixo, segure-a com a direita na parte superior para poder extrair o conteúdo, como em:
A.splice(0, A.length);
Não, você foi solicitado a esvaziá-lo:
A.length = 0;
Este é o único código que esvazia corretamente o conteúdo de uma determinada matriz JavaScript.
A(n) = A.splice( 0, A.length );
caso de você precisar fazer backup de seu conteúdo anterior. ps Array.length
é uma propriedade de leitura-gravação \ método, caso você tenha esquecido esse fato básico. Ou seja, você pode expandi-lo para um novo comprimento, não pode cortá-lo para o comprimento que desejar e, entre outros, você pode descartar todos os membros encurtando seu comprimento para 0. É um canivete suíço da matriz.
Teste 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
Você pode adicionar isso ao seu arquivo JavaScript para permitir que suas matrizes sejam "limpas":
Array.prototype.clear = function() {
this.splice(0, this.length);
};
Então você pode usá-lo assim:
var list = [1, 2, 3];
list.clear();
Ou se você quiser ter certeza de que não destrói algo:
if (!Array.prototype.clear) {
Array.prototype.clear = function() {
this.splice(0, this.length);
};
}
Muitas pessoas pensam que você não deve modificar objetos nativos (como Array), e estou inclinado a concordar. Por favor, tenha cuidado ao decidir como lidar com isso.
clear
chave?
Há muita confusão e desinformação quanto ao tempo; desempenho pop / shift tanto em respostas quanto em comentários. A solução while / pop tem (como esperado) o pior desempenho . O que realmente está acontecendo é que a instalação é executada apenas uma vez para cada amostra que executa o snippet em um loop. por exemplo:
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
}
}
Eu criei um novo teste que funciona corretamente:
http://jsperf.com/empty-javascript-array-redux
Aviso: mesmo nesta versão do teste, você não consegue ver a diferença real porque a clonagem da matriz ocupa a maior parte do tempo do teste. Ele ainda mostra que splice
é a maneira mais rápida de limpar a matriz (sem levar []
em consideração porque, embora seja a mais rápida, na verdade não está limpando a matriz existente).
Caso esteja interessado na alocação de memória, você pode comparar cada abordagem usando algo como este jsfiddle em conjunto com a guia da linha do tempo das ferramentas de desenvolvimento do chrome. Você deseja usar o ícone da lixeira na parte inferior para forçar uma coleta de lixo após 'limpar' a matriz. Isso deve fornecer uma resposta mais definitiva para o navegador de sua escolha. Muitas respostas aqui são antigas e eu não confiaria nelas, mas sim testarei como na resposta de @ tanguy_k acima.
(para uma introdução à guia mencionada acima, você pode conferir aqui )
Stackoverflow me obriga a copiar o jsfiddle, então aqui está:
<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>
E você deve observar que isso pode depender do tipo dos elementos da matriz, pois o javascript gerencia seqüências de caracteres de maneira diferente de outros tipos primitivos, sem mencionar as matrizes de objetos. O tipo pode afetar o que acontece.
Você pode criar facilmente uma função para fazer isso por você, alterar o comprimento ou até adicioná-la à matriz nativa como remove()
função para reutilização.
Imagine que você tem esta matriz:
var arr = [1, 2, 3, 4, 5]; //the array
OK, basta executar o seguinte:
arr.length = 0; //change the length
e o resultado é:
[] //result
maneira fácil de esvaziar uma matriz ...
Também usando loop que não é necessário, mas apenas outra maneira de fazer isso:
/* 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();
}
}
Também há maneiras difíceis de pensar, por exemplo, algo como isto:
arr.splice(0, arr.length); //[]
Portanto, se arr tiver 5 itens, ele dividirá 5 itens de 0, o que significa que nada permanecerá na matriz.
Outras maneiras, como simplesmente reatribuir a matriz, por exemplo:
arr = []; //[]
Se você observar as funções de matriz, existem muitas outras maneiras de fazer isso, mas a mais recomendada pode ser a alteração do comprimento.
Como eu disse em primeiro lugar, você também pode criar protótipo remove (), pois é a resposta para sua pergunta. você pode simplesmente escolher um dos métodos acima e prototipá-lo para o objeto Array em JavaScript, algo como:
Array.prototype.remove = Array.prototype.remove || function() {
this.splice(0, this.length);
};
e você pode simplesmente chamar assim para esvaziar qualquer matriz em seu aplicativo javascript:
arr.remove(); //[]
Array.prototype.clear = function() {
this.length = 0;
};
E chame: array.clear();
A.splice(0);
Eu fiz isso em algum código no qual estou trabalhando. Limpou a matriz.
Se você estiver usando
a = [];
Em seguida, você está atribuindo uma nova referência de matriz a, se a referência em a já estiver atribuída a qualquer outra variável, ela também não esvaziará a matriz e, portanto, o coletor de lixo não coletará essa memória.
Por ex.
var a=[1,2,3];
var b=a;
a=[];
console.log(b);// It will print [1,2,3];
ou
a.length = 0;
Quando especificamos a.length
, estamos apenas redefinindo os limites da matriz e a memória para os elementos restantes da matriz serão conectados pelo coletor de lixo.
Em vez destas duas soluções são melhores.
a.splice(0,a.length)
e
while(a.length > 0) {
a.pop();
}
Conforme a resposta anterior de kenshou.html, o segundo método é mais rápido.
a.length
, não vejo o que essa nova resposta adiciona ao tópico?
a.length=0;
forem executados? Como esses motores agem a.length=500;
e a.length=4;
?
var a = [1]; var b = a; a.length = 0; console.log(b)
imprime Array [ ]
, para que não pareça estar criando uma nova matriz para mim.
Se você usa constantes, não tem escolha:
const numbers = [1, 2, 3]
Você não pode reasign:
numbers = []
Você só pode truncar:
numbers.length = 0
Para esvaziar um local de memória atual de uma matriz, use: 'myArray.length = 0'
ou'myArray.pop() UN-till its length is 0'
length
: Você pode definir a propriedade length para truncar uma matriz a qualquer momento. Quando você estende uma matriz alterando sua propriedade length, o número de elementos reais aumenta.pop()
: O método pop remove o último elemento de uma matriz e retorna que retorna o valor removido.shift()
: O método shift remove o elemento no índice zeroeth e desloca os valores em índices consecutivos para baixo e retorna o valor removido.Exemplo:
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() | []
Crie uma matriz com a nova localização da memória usando 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()
: Ao usar a função de fatia, obtemos uma cópia superficial dos elementos da matriz original, com novo endereço de memória, para que qualquer modificação no cloneArr não afete uma matriz original.
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 = ?
vez de apenas length
.
Estou surpreso que ninguém tenha sugerido isso ainda:
let xs = [1,2,3,4];
for (let i in xs)
delete xs[i];
Isso gera uma matriz em um estado completamente diferente das outras soluções. Em certo sentido, a matriz foi 'esvaziada':
xs
=> Array [ <4 empty slots> ]
[...xs]
=> Array [ undefined, undefined, undefined, undefined ]
xs.length
=> 4
xs[0]
=> ReferenceError: reference to undefined property xs[0]
Você pode produzir uma matriz equivalente com [,,,,]
ouArray(4)
Use abaixo se você precisar esvaziar o Angular 2+ FormArray.
public emptyFormArray(formArray:FormArray) {
for (let i = formArray.controls.length - 1; i >= 0; i--) {
formArray.removeAt(i);
}
}