splice - Como faço para esvaziar uma matriz em JavaScript?




unset array javascript (12)

As respostas que não têm menos que 2739 até agora são enganosas e incorretas.

A pergunta é: "Como você esvazia sua matriz existente?" Por exemplo, para A = [1,2,3,4] .

  1. 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 conta própria.

Digamos que sua mãe lhe peça para esvaziar a lata de lixo.

  • Você não traz um novo como se tivesse feito o que lhe pediram.
  • Em vez disso, você esvazia a lixeira.
  • Você não substitui o preenchido com uma nova lata vazia, e você não pega o rótulo "A" da lata cheia e colá-lo ao novo como em A = [1,2,3,4]; A = []; A = [1,2,3,4]; A = [];

Esvaziar um objeto de matriz é a coisa mais fácil de todas:

A.length = 0;

Desta forma, a lata em "A" não é apenas vazia, mas também limpa como nova!

  1. Além disso, você não é obrigado a remover o lixo com a mão até que a lata esteja vazia! Você foi convidado a esvaziar o existente, completamente, em um turno, para não pegar o lixo até que a lata ficasse vazia, como em:

    while(A.length > 0) {
        A.pop();
    }
    
  2. Também não coloque a mão esquerda no fundo do lixo, segurando-a com a sua direita no topo para poder puxar o seu conteúdo como em:

    A.splice(0, A.length);
    

Não, você foi solicitado a esvaziá-lo:

A.length = 0;

Esse é o único código que esvazia corretamente o conteúdo de um determinado array JavaScript.

Existe uma maneira de esvaziar uma matriz e, se possível, com .remove() ?

Por exemplo,

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

Como posso esvaziar isso?


Caso você esteja interessado na alocação de memória, você pode comparar cada abordagem usando algo como este jsfiddle em conjunto com a aba cronograma das ferramentas do cromo dev. Você vai querer usar o ícone da lixeira na parte inferior para forçar uma coleta de lixo após 'limpar' a matriz. Isso deve lhe dar uma resposta mais definida para o navegador de sua escolha. Muitas respostas aqui são antigas e eu não confiaria nelas, mas sim no teste como na resposta de @ tanguy_k acima.

(para uma introdução à aba mencionada, você pode conferir here )

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 pode depender do tipo dos elementos da matriz, já que o javascript gerencia strings de maneira diferente de outros tipos primitivos, sem mencionar arrays de objetos. O tipo pode afetar o que acontece.


Formas de limpar um array existente A :

Método 1

(esta foi a minha resposta original à pergunta)

A = [];

Este código irá definir a variável A para um novo array vazio. Isso é perfeito se você não tiver referências ao array original A nenhum outro lugar, porque isso realmente cria um novo array (vazio). Você deve ter cuidado com esse método, porque se você referenciou esse array de outra variável ou propriedade, o array original permanecerá inalterado. Só use isso se você fizer referência apenas à matriz por sua variável original.

Esta é 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 (como suggested 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. Ele 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 suggested por Anthony )

A.splice(0,A.length)

O uso de .splice() funcionará perfeitamente, mas como a função .splice() retornará uma matriz com todos os itens removidos, ela retornará uma cópia da matriz original. Os benchmarks sugerem que isso não tem efeito algum sobre o desempenho.

Método 4 (como suggested por tanguy_k )

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

Esta solução não é muito sucinta, e é também a solução mais lenta, ao contrário dos benchmarks anteriores referenciados na resposta original.

atuação

De todos os métodos de limpeza de um array existente , os métodos 2 e 3 são muito semelhantes em desempenho e são muito mais rápidos que o método 4. Veja este benchmark .

Como apontado por Diadistis em sua answer abaixo, os benchmarks originais que foram usados ​​para determinar o desempenho dos quatro métodos descritos acima foram falhos. O benchmark original reutilizou o array limpo, então a segunda iteração estava limpando um array que já estava vazio.

O seguinte benchmark corrige essa falha: benchmark . Isso mostra claramente que os métodos # 2 (length) e # 3 (splice) são os mais rápidos (sem contar o método # 1, que não altera o array original).

Este tem sido um tema quente e a causa de muita controvérsia. Na verdade, existem muitas respostas corretas e, como essa resposta foi marcada como a resposta aceita por um tempo muito longo, incluirei todos os métodos aqui. Se você votar nessa resposta, por favor, vote nas outras respostas que referi também.


Há muita confusão e desinformação sobre o tempo, desempenho pop / turno tanto nas respostas quanto nos 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 pode realmente ver a diferença real, porque a clonagem do array ocupa a maior parte do tempo de teste. Ele ainda mostra que splice é a maneira mais rápida de limpar a matriz (não levando [] em consideração porque, embora seja a mais rápida, ela não está realmente limpando a matriz existente).


Se você precisar manter o array original porque você tem outras referências a ele que também devem ser atualizadas, você pode limpá-lo sem criar um novo array definindo seu tamanho como zero:

A.length = 0;

Se você usar constantes, não terá escolha:

const numbers = [1, 2, 3]

Você não pode reasign:

numbers = []

Você só pode truncar:

numbers.length = 0

Uma solução mais amigável e mais otimizada para o navegador cruzado será usar o método splice para esvaziar o conteúdo do array A como abaixo:

A.splice(0, A.length);


Use abaixo se precisar esvaziar o Angular 2+ FormArray.

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

Você pode adicionar isso ao seu arquivo JavaScript para permitir que seus arrays sejam "limpos":

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 não destruir algo:

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

Muitas pessoas acham que você não deve modificar objetos nativos (como o Array), e estou inclinado a concordar. Por favor, tenha cuidado ao decidir como lidar com isso.


Você pode facilmente criar uma função para fazer isso por você, alterar o comprimento ou até mesmo adicioná-lo ao Array nativo como função remove() para reutilização.

Imagine que você tenha esse array:

var arr = [1, 2, 3, 4, 5]; //the array

OK, simplesmente execute isto:

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 uma 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(); 
  }
}

Há também uma maneira complicada que você pode pensar, por exemplo, algo como isto:

arr.splice(0, arr.length); //[]

Então, se arr tem 5 itens, ele irá emendar 5 itens de 0, o que significa que nada permanecerá na matriz.

Também outras maneiras, como simplesmente reatribuir o array, por exemplo:

arr = []; //[]

Se você observar as funções do Array, há muitas outras maneiras de fazer isso, mas a mais recomendada pode ser alterar o tamanho.

Como eu disse em primeiro lugar, você também pode prototipar remove () como é 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 chamá-lo assim para esvaziar qualquer array em seu aplicativo de javascript:

arr.remove(); //[]

A.splice(0);

Eu fiz isso em algum código que estou trabalhando. Ele limpou o array.


Aqui a implementação de trabalho mais rápida , mantendo o mesmo array ("mutável"):

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

FYI Map define clear() portanto, parece lógico ter clear() para Array também.

Ou como um mix de Underscore.js :

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

Ou uma função simples:

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

Versão do TypeScript :

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

FYI não pode ser simplificado para while (array.pop()) : os testes falharão.

E os testes que acompanham isso:

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);
  });
});

Aqui o jsPerf atualizado: http://jsperf.com/array-destroy/32 http://jsperf.com/array-destroy/152





arrays