arrays array object - Como faço para remover um elemento particular de uma matriz em JavaScript?





15 Answers

Eu não sei como você está esperando array.remove(int) se comportar. Há três possibilidades que posso pensar que você pode estar querendo.

Para remover um elemento de uma matriz em um índice i :

array.splice(i, 1);

Se você quiser remover todos os elementos com o number do valor da matriz:

for(var i = array.length - 1; i >= 0; i--) {
    if(array[i] === number) {
       array.splice(i, 1);
    }
}

Se você quiser apenas fazer com que o elemento no índice i não exista mais, mas você não quer que os índices dos outros elementos sejam alterados:

delete array[i];
from objeto splice

Eu tenho uma matriz de inteiros e estou usando o método .push() para adicionar elementos a ele.

Existe uma maneira simples de remover um elemento específico de uma matriz? O equivalente a algo como array.remove(int); .

Eu tenho que usar o núcleo do JavaScript - nenhum framework é permitido.




Depende se você quer manter um local vazio ou não.

Se você quer um slot vazio, delete está bem:

delete array[ index ];

Se você não fizer isso, você deve usar o método splice :

array.splice( index, 1 );

E se você precisar do valor desse item, você pode apenas armazenar o elemento da matriz retornada:

var value = array.splice( index, 1 )[0];

Caso você queira fazer isso em alguma ordem, você pode usar array.pop() para o último ou array.shift() para o primeiro (e ambos retornam o valor do item também).

E se você não sabe o índice do item, você pode usar array.indexOf( item ) para obtê-lo (em um if() para obter um item ou em um while() para obter todos eles). array.indexOf( item ) retorna o índice ou -1 se não for encontrado.




Existem duas abordagens principais:

  1. splice () : anArray.splice(index, 1);

  2. delete : delete anArray[index];

Tenha cuidado ao usar excluir para uma matriz. É bom para excluir atributos de objetos, mas não tão bons para matrizes. É melhor usar splice para matrizes.

Tenha em mente que quando você usa delete para um array, você pode obter resultados errados para anArray.length . Em outras palavras, delete removeria o elemento, mas não atualizaria o valor da propriedade length.

Você também pode esperar ter buracos nos números de índice depois de usar delete, por exemplo, você pode acabar tendo índices 1,3,4,8,9,11 e length como era antes de usar delete. Nesse caso, todos os loops indexados falharão, já que os índices não são mais sequenciais.

Se você for forçado a usar o delete por algum motivo, então você deve usar for each loop quando precisar fazer um loop por arrays. De fato, sempre evite usar loops indexados, se possível. Dessa forma, o código seria mais robusto e menos propenso a problemas com índices.




Não há necessidade de usar indexOf ou splice . No entanto, ele funciona melhor se você quiser apenas remover uma ocorrência de um elemento.

Encontre e mova (mova):

function move(arr, val) {
  var j = 0;
  for (var i = 0, l = arr.length; i < l; i++) {
    if (arr[i] !== val) {
      arr[j++] = arr[i];
    }
  }
  arr.length = j;
}

Use indexOf e splice (indexof):

function indexof(arr, val) {
  var i;
  while ((i = arr.indexOf(val)) != -1) {
    arr.splice(i, 1);
  }
}

Use apenas splice (emenda):

function splice(arr, val) {
  for (var i = arr.length; i--;) {
    if (arr[i] === val) {
      arr.splice(i, 1);
    }
  }
}

Tempos de execução em nodejs para matriz com 1000 elementos (média acima de 10000 execuções):

indexof é aproximadamente 10x mais lento que o movimento . Mesmo se melhorado, removendo a chamada para indexOf na emenda, ele executa muito pior do que mover .

Remove all occurrences:
    move 0.0048 ms
    indexof 0.0463 ms
    splice 0.0359 ms

Remove first occurrence:
    move_one 0.0041 ms
    indexof_one 0.0021 ms



John Resig postou uma boa implementação :

// Array Remove - By John Resig (MIT Licensed)
Array.prototype.remove = function(from, to) {
  var rest = this.slice((to || from) + 1 || this.length);
  this.length = from < 0 ? this.length + from : from;
  return this.push.apply(this, rest);
};

Se você não quiser estender um objeto global, poderá fazer algo como o seguinte:

// Array Remove - By John Resig (MIT Licensed)
Array.remove = function(array, from, to) {
    var rest = array.slice((to || from) + 1 || array.length);
    array.length = from < 0 ? array.length + from : from;
    return array.push.apply(array, rest);
};

Mas a principal razão pela qual estou postando isso é alertar os usuários contra a implementação alternativa sugerida nos comentários nessa página (14 de dezembro de 2007):

Array.prototype.remove = function(from, to){
  this.splice(from, (to=[0,from||1,++to-from][arguments.length])<0?this.length+to:to);
  return this.length;
};

Parece funcionar bem no começo, mas através de um processo doloroso eu descobri que ele falha ao tentar remover o segundo para o último elemento em uma matriz. Por exemplo, se você tiver uma matriz de 10 elementos e tentar remover o 9º elemento com isto:

myArray.remove(8);

Você acaba com uma matriz de 8 elementos. Não sei porque, mas eu confirmei que a implementação original de John não tem esse problema.




Você pode fazer isso facilmente com o método de filter :

function remove(arrOriginal, elementToRemove){
    return arrOriginal.filter(function(el){return el !== elementToRemove});
}
console.log( remove([1, 2, 1, 0, 3, 1, 4], 1) );

Isso remove todos os elementos da matriz e também funciona mais rápido do que a combinação de fatia e indexOf




Você pode usar o ES6.

var array=['1','2','3','4','5','6']
var index = array.filter((value)=>value!='3');

Saída:

["1", "2", "4", "5", "6"]



Você pode usar lodash _.pull (matriz mutate), _.pullAt (matriz mutate) ou _.without (não _.without array),

var array1 = ['a', 'b', 'c', 'd']
_.pull(array1, 'c')
console.log(array1) // ['a', 'b', 'd']

var array2 = ['e', 'f', 'g', 'h']
_.pullAt(array2, 0)
console.log(array2) // ['f', 'g', 'h']

var array3 = ['i', 'j', 'k', 'l']
var newArray = _.without(array3, 'i') // ['j', 'k', 'l']
console.log(array3) // ['i', 'j', 'k', 'l']



Sou novo em JavaScript e precisava dessa funcionalidade. Eu simplesmente escrevi isso:

function removeFromArray(array, item, index) {
  while((index = array.indexOf(item)) > -1) {
    array.splice(index, 1);
  }
}

Então quando eu quiser usá-lo:

//Set-up some dummy data
var dummyObj = {name:"meow"};
var dummyArray = [dummyObj, "item1", "item1", "item2"];

//Remove the dummy data
removeFromArray(dummyArray, dummyObj);
removeFromArray(dummyArray, "item2");

Saída - como esperado. ["item1", "item1"]

Você pode ter necessidades diferentes de mim, então você pode facilmente modificá-lo para se adequar a elas. Espero que isso ajude alguém.




Atualização: Este método é recomendado somente se você não puder usar o ECMAScript 2015 (anteriormente conhecido como ES6). Se você puder usá-lo, outras respostas aqui fornecem implementações muito mais simples.

Essa essência aqui resolverá seu problema e também excluirá todas as ocorrências do argumento em vez de apenas 1 (ou um valor especificado).

Array.prototype.destroy = function(obj){
    // Return null if no objects were found and removed
    var destroyed = null;

    for(var i = 0; i < this.length; i++){

        // Use while-loop to find adjacent equal objects
        while(this[i] === obj){

            // Remove this[i] and store it within destroyed
            destroyed = this.splice(i, 1)[0];
        }
    }

    return destroyed;
}

Uso:

var x = [1, 2, 3, 3, true, false, undefined, false];

x.destroy(3);         // => 3
x.destroy(false);     // => false
x;                    // => [1, 2, true, undefined]

x.destroy(true);      // => true
x.destroy(undefined); // => undefined
x;                    // => [1, 2]

x.destroy(3);         // => null
x;                    // => [1, 2]



Você nunca deve transformar seu array em array. Como isso é contra o padrão de programação funcional. O que você pode fazer é criar uma nova matriz sem fazer referência à matriz que você deseja alterar os dados usando o filter método es6;

var myArray = [1,2,3,4,5,6];

Suponha que você queira remover 5 da matriz, você pode simplesmente fazer assim.

myArray = myArray.filter(value => value !== 5);

Isso fornecerá uma nova matriz sem o valor que você deseja remover. Então o resultado será

 [1,2,3,4,6]; // 5 has been removed from this array

Para entender melhor, você pode ler a documentação do MDN em Array.filter filter




Uma abordagem mais moderna, ECMAScript 2015 (anteriormente conhecida como Harmony ou ES 6). Dado:

const items = [1, 2, 3, 4];
const index = 2;

Então:

items.filter((x, i) => i !== index);

Produzindo:

[1, 2, 4]

Você pode usar o Babel e um serviço de polyfill para garantir que isso seja bem suportado em todos os navegadores.




Eu tenho outra boa solução para remover de uma matriz:

var words = ['spray', 'limit', 'elite', 'exuberant', 'destruction', 'present'];

const result = words.filter(word => word.length > 6);

console.log(result);
// expected output: Array ["exuberant", "destruction", "present"]

filter




Com base em todas as respostas que estavam corretas e levando em consideração as melhores práticas sugeridas (especialmente não usando o Array.prototype diretamente), eu criei o código abaixo:

function arrayWithout(arr, values) {
  var isArray = function(canBeArray) {
    if (Array.isArray) {
      return Array.isArray(canBeArray);
    }
    return Object.prototype.toString.call(canBeArray) === '[object Array]';
  };

  var excludedValues = (isArray(values)) ? values : [].slice.call(arguments, 1);
  var arrCopy = arr.slice(0);

  for (var i = arrCopy.length - 1; i >= 0; i--) {
    if (excludedValues.indexOf(arrCopy[i]) > -1) {
      arrCopy.splice(i, 1);
    }
  }

  return arrCopy;
}

Revendo a função acima, apesar do fato de que funciona bem, percebi que poderia haver alguma melhora no desempenho. Também usar ES6 em vez de ES5 é uma abordagem muito melhor. Para esse fim, esse é o código aprimorado:

const arrayWithoutFastest = (() => {
  const isArray = canBeArray => ('isArray' in Array) 
    ? Array.isArray(canBeArray) 
    : Object.prototype.toString.call(canBeArray) === '[object Array]';

  let mapIncludes = (map, key) => map.has(key);
  let objectIncludes = (obj, key) => key in obj;
  let includes;

  function arrayWithoutFastest(arr, ...thisArgs) {
    let withoutValues = isArray(thisArgs[0]) ? thisArgs[0] : thisArgs;

    if (typeof Map !== 'undefined') {
      withoutValues = withoutValues.reduce((map, value) => map.set(value, value), new Map());
      includes = mapIncludes;
    } else {
      withoutValues = withoutValues.reduce((map, value) => { map[value] = value; return map; } , {}); 
      includes = objectIncludes;
    }

    const arrCopy = [];
    const length = arr.length;

    for (let i = 0; i < length; i++) {
      // If value is not in exclude list
      if (!includes(withoutValues, arr[i])) {
        arrCopy.push(arr[i]);
      }
    }

    return arrCopy;
  }

  return arrayWithoutFastest;  
})();

Como usar:

const arr = [1,2,3,4,5,"name", false];

arrayWithoutFastest(arr, 1); // will return array [2,3,4,5,"name", false]
arrayWithoutFastest(arr, 'name'); // will return [2,3,4,5, false]
arrayWithoutFastest(arr, false); // will return [2,3,4,5]
arrayWithoutFastest(arr,[1,2]); // will return [3,4,5,"name", false];
arrayWithoutFastest(arr, {bar: "foo"}); // will return the same array (new copy)

No momento, estou escrevendo um post de blog no qual testei várias soluções para o Array sem problemas e comparei o tempo necessário para executá-lo. Eu atualizarei esta resposta com o link assim que terminar esse post. Só para você saber, eu comparei o anterior com o da lodash sem e no caso do navegador suporta Map, ele bate lodash! Note que eu não estou usando Array.prototype.indexOfou Array.prototype.includesenvolvendo os exlcudeValues ​​em um Mapou Objectfaz consultas mais rápidas! ( https://jsperf.com/array-without-benchmark-against-lodash )




Você tem 1 a 9 array e você quer remover 5 use abaixo do código.

var numberArray = [1, 2, 3, 4, 5, 6, 7, 8, 9];

var newNumberArray = numberArray.filter(m => {
  return m !== 5;
});

console.log("new Array, 5 removed", newNumberArray);

Se você quiser um valor múltiplo ex: - 1,7,8

var numberArray = [1, 2, 3, 4, 5, 6, 7, 8, 9];

var newNumberArray = numberArray.filter(m => {
  return (m !== 1) && (m !== 7) && (m !== 8);
});

console.log("new Array, 5 removed", newNumberArray);

Se você quiser remover o valor da matriz na matriz ex: - [3,4,5]

var numberArray = [1, 2, 3, 4, 5, 6, 7, 8, 9];
var removebleArray = [3,4,5];

var newNumberArray = numberArray.filter(m => {
    return !removebleArray.includes(m);
});

console.log("new Array, [3,4,5] removed", newNumberArray);

inclui navegador suportado é link




Related