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




first pop (25)

Você pode fazer um loop para trás para certificar-se de não estragar os índices, se houver várias instâncias do elemento.

var myElement = "chocolate";
var myArray = ['chocolate', 'poptart', 'poptart', 'poptart', 'chocolate', 'poptart', 'poptart', 'chocolate'];

/* Important code */
for (var i = myArray.length - 1; i >= 0; i--) {
    if (myArray[i] == myElement) myArray.splice(i, 1);
}

Demonstração ao vivo

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.


Editado em 2016 outubro

  • Faça isso de forma simples, intuitiva e explícita ( https://en.wikipedia.org/wiki/Occam%27s_razor )
  • Faça-o imutável (matriz original permanece inalterada)
  • Faça isso com as funções padrão do JS, se o seu navegador não as suportar - use o polyfill

Neste exemplo de código eu uso a função "array.filter (...)" para remover itens indesejados da matriz, essa função não altera a matriz original e cria uma nova. Se o seu navegador não suportar esta função (por exemplo, o IE antes da versão 9 ou o Firefox antes da versão 1.5), considere o uso do filtro polyfill da Mozilla .

Removendo o item (código ECMA-262 Edição 5, conhecido como oldstyle JS)

var value = 3

var arr = [1, 2, 3, 4, 5, 3]

arr = arr.filter(function(item) { 
    return item !== value
})

console.log(arr)
// [ 1, 2, 4, 5 ]

Removendo item (código ES2015)

let value = 3

let arr = [1, 2, 3, 4, 5, 3]

arr = arr.filter(item => item !== value)

console.log(arr)
// [ 1, 2, 4, 5 ]

IMPORTANTE ES2015 "() => {}" a sintaxe da função de seta não é suportada no IE, o Chrome antes da versão 45, o Firefox antes da versão 22, o Safari antes da versão 10. Para usar a sintaxe do ES2015 em navegadores antigos, você pode usar o BabelJS

Removendo vários itens (código ES2016)

Uma vantagem adicional desse método é que você pode remover vários itens

let forDeletion = [2, 3, 5]

let arr = [1, 2, 3, 4, 5, 3]

arr = arr.filter(item => !forDeletion.includes(item))
// !!! Read below about array.includes(...) support !!!

console.log(arr)
// [ 1, 4 ]

IMPORTANTE A função "array.includes (...)" não é suportada no IE, Chrome antes da versão 47, Firefox antes da versão 43, Safari antes da versão 9 e Edge antes da versão 14 então aqui está o polyfill da Mozilla

Removendo vários itens (JavaScript experimental de ponta ES2018?)

// array-lib.js

export function remove(...forDeletion) {
    return this.filter(item => !forDeletion.includes(item))
}

// main.js

import { remove } from './array-lib.js'

let arr = [1, 2, 3, 4, 5, 3]

// :: This-Binding Syntax Proposal
// using "remove" function as "virtual method"
// without extending Array.prototype
arr = arr::remove(2, 3, 5)

console.log(arr)
// [ 1, 4 ]

Tente você mesmo em BabelJS :)

Referência


Eu sei que já existem muitas respostas, mas muitas delas parecem complicar demais o problema. Aqui está uma maneira simples e recursiva de remover todas as instâncias de uma chave - chama-se auto até que o índice não seja encontrado. Sim, funciona apenas em navegadores indexOf, mas é simples e pode ser facilmente preenchido.

Função autônoma

function removeAll(array, key){
    var index = array.indexOf(key);

    if(index === -1) return;

    array.splice(index, 1);
    removeAll(array,key);
}

Método de protótipo

Array.prototype.removeAll = function(key){
    var index = this.indexOf(key);

    if(index === -1) return;

    this.splice(index, 1);
    this.removeAll(key);
}

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.


Aqui estão algumas maneiras de remover um item de uma matriz usando JavaScript .

Todo o método descrito não altera o array original e cria um novo.

Se você conhece o índice de um item

Suponha que você tenha uma matriz e deseje remover um item na posição i .

Um método é usar slice() :

const items = ['a', 'b', 'c', 'd', 'e', 'f']
const i = 3
const filteredItems = items.slice(0, i-1).concat(items.slice(i, items.length))

console.log(filteredItems)

slice() cria um novo array com os índices que recebe. Nós simplesmente criamos uma nova matriz, do início ao índice que queremos remover, e concatenamos outra matriz da primeira posição após a que removemos até o final da matriz.

Se você conhece o valor

Nesse caso, uma boa opção é usar filter() , que oferece uma abordagem mais declarativa :

const items = ['a', 'b', 'c', 'd', 'e', 'f']
const valueToRemove = 'c'
const filteredItems = items.filter(item => item !== valueToRemove)

console.log(filteredItems)

Isso usa as funções de seta do ES6. Você pode usar as funções tradicionais para suportar navegadores mais antigos:

const items = ['a', 'b', 'c', 'd', 'e', 'f']
const valueToRemove = 'c'
const filteredItems = items.filter(function(item) {
  return item !== valueToRemove
})

console.log(filteredItems)

ou você pode usar o Babel e transpilar o código ES6 de volta para o ES5 para torná-lo mais digerível para navegadores antigos, e ainda escrever JavaScript moderno em seu código.

Removendo vários itens

E se, em vez de um único item, você quiser remover muitos itens?

Vamos encontrar a solução mais simples.

Por índice

Você pode apenas criar uma função e remover itens em série:

const items = ['a', 'b', 'c', 'd', 'e', 'f']

const removeItem = (items, i) =>
  items.slice(0, i-1).concat(items.slice(i, items.length))

let filteredItems = removeItem(items, 3)
filteredItems = removeItem(filteredItems, 5)
//["a", "b", "c", "d"]

console.log(filteredItems)

Por valor

Você pode procurar por inclusão dentro da função de retorno de chamada:

const items = ['a', 'b', 'c', 'd', 'e', 'f']
const valuesToRemove = ['c', 'd']
const filteredItems = items.filter(item => !valuesToRemove.includes(item))
// ["a", "b", "e", "f"]

console.log(filteredItems)

Evite mudar o array original

splice() (não deve ser confundido com slice() ) muta a matriz original e deve ser evitado.

(originalmente publicado em https://flaviocopes.com/how-to-remove-item-from-array/ )


Se você quiser uma nova matriz com as posições excluídas removidas, você sempre poderá excluir o elemento específico e filtrar a matriz. Pode ser necessário uma extensão do objeto de matriz para navegadores que não implementam o método de filtro, mas, no longo prazo, é mais fácil, já que tudo que você faz é isto:

var my_array = [1,2,3,4,5,6];
delete my_array[4];
console.log(my_array.filter(function(a){return typeof a !== 'undefined';}));

Deve exibir [1, 2, 3, 4, 6]


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ê 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


Underscore.js pode ser usado para resolver problemas com vários navegadores. Ele usa métodos de navegador embutido, se presentes. Se eles estiverem ausentes, como no caso de versões mais antigas do Internet Explorer, ele usa seus próprios métodos personalizados.

Um exemplo simples para remover elementos da matriz (do site):

_.without([1, 2, 1, 0, 3, 1, 4], 0, 1); // => [2, 3, 4]

Confira este código. Funciona em todos os principais navegadores .

remove_item = function (arr, value) {
    var b = '';
    for (b in arr) {
        if (arr[b] === value) {
            arr.splice(b, 1);
            break;
        }
    }
    return arr;
}

Chame essa função

remove_item(array,value);

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.


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


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

  Array.prototype.removeItem = function(a) {
            for (i = 0; i < this.length; i++) {
                if (this[i] == a) {
                    for (i2 = i; i2 < this.length - 1; i2++) {
                        this[i2] = this[i2 + 1];
                    }
                    this.length = this.length - 1
                    return;
                }
            }
        }

    var recentMovies = ['Iron Man', 'Batman', 'Superman', 'Spiderman'];
    recentMovies.removeItem('Superman');

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']

Encontre o index do elemento da matriz que você deseja remover e remova esse índice com splice .

O método splice () altera o conteúdo de um array removendo elementos existentes e / ou adicionando novos elementos.

var array = [2, 5, 9];
console.log(array)
var index = array.indexOf(5);
if (index > -1) {
  array.splice(index, 1);
}
// array = [2, 9]
console.log(array);

O segundo parâmetro da splice é o número de elementos a serem removidos. Observe que a splice modifica a matriz no lugar e retorna uma nova matriz contendo os elementos que foram removidos.

Nota : o suporte do navegador para indexOf é limitado; não é suportado no Internet Explorer 7 e 8.

Se você precisar de indexOf em um navegador não suportado, tente o seguinte polyfill . Encontre mais informações sobre este polyfill aqui .

Array.prototype.indexOf || (Array.prototype.indexOf = function(d, e) {
    var a;
    if (null == this) throw new TypeError('"this" is null or not defined');
    var c = Object(this),
        b = c.length >>> 0;
    if (0 === b) return -1;
    a = +e || 0;
    Infinity === Math.abs(a) && (a = 0);
    if (a >= b) return -1;
    for (a = Math.max(0 <= a ? a : b - Math.abs(a), 0); a < b;) {
        if (a in c && c[a] === d) return a;
        a++
    }
    return -1
});

Se você tem objetos complexos na matriz, você pode usar filtros? Em situações em que $ .inArray ou array.splice não é tão fácil de usar. Especialmente se os objetos são talvez rasos na matriz.

Por exemplo, se você tem um objeto com um campo Id e deseja que o objeto seja removido de uma matriz:

this.array = this.array.filter(function(element, i) {
    return element.id !== idToRemove;
});

OK, por exemplo, você está tendo o array abaixo:

var num = [1, 2, 3, 4, 5];

E nós queremos excluir o número 4, você pode simplesmente fazer o código abaixo:

num.splice(num.indexOf(4), 1); //num will be [1, 2, 3, 5];

Se você reutilizar esta função, você escreverá uma função reutilizável que será anexada à função de matriz nativa como abaixo:

Array.prototype.remove = Array.prototype.remove || function(x) {
  const i = this.indexOf(x);
  if(i===-1) return;
  this.splice(i, 1); //num.remove(5) === [1, 2, 3];
}

Mas e se você tiver o array abaixo em vez de alguns [5] s no Array?

var num = [5, 6, 5, 4, 5, 1, 5];

Precisamos de um loop para verificar todos eles, mas a maneira mais fácil e eficiente é usar funções JavaScript integradas, então escrevemos uma função que usa filtro como abaixo:

const _removeValue = (arr, x) => arr.filter(n => n!==x);
//_removeValue([1, 2, 3, 4, 5, 5, 6, 5], 5) //return [1, 2, 3, 4, 6]

Além disso, há bibliotecas de terceiros que ajudam você a fazer isso, como o Lodash ou o Underscore, para obter mais informações, consulte lodash _.pull, _.pullAt ou _.without.


Um amigo estava tendo problemas no Internet Explorer 8 e me mostrou o que ele fez. Eu disse a ele que estava errado e ele me disse que tinha a resposta aqui. A resposta principal atual não funcionará em todos os navegadores (Internet Explorer 8, por exemplo) e somente removerá a primeira ocorrência do item.

Remover TODAS as instâncias de um array

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

Ele percorre a matriz de trás para frente (pois os índices e o comprimento serão alterados à medida que os itens são removidos) e remove o item, se ele for encontrado. Funciona em todos os navegadores.


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


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ê 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


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]

Este é um iterador para a lista NON-SPARSE, onde o índice começa em 0, que é o cenário típico quando se lida com document.getElementsByTagName ou document.querySelectorAll)

function each( fn, data ) {

    if(typeof fn == 'string')
        eval('fn = function(data, i){' + fn + '}');

    for(var i=0, L=this.length; i < L; i++) 
        fn.call( this[i], data, i );   

    return this;
}

Array.prototype.each = each;  

Exemplos de uso:

Exemplo 1

var arr = [];
[1, 2, 3].each( function(a){ a.push( this * this}, arr);
arr = [1, 4, 9]

Exemplo # 2

each.call(document.getElementsByTagName('p'), "this.className = data;",'blue');

Cada tag p recebe class="blue"

Exemplo # 3

each.call(document.getElementsByTagName('p'), 
    "if( i % 2 == 0) this.className = data;",
    'red'
);

Todas as outras tags p recebem class="red">

Exemplo # 4

each.call(document.querySelectorAll('p.blue'), 
    function(newClass, i) {
        if( i < 20 )
            this.className = newClass;
    }, 'green'
);

E finalmente as primeiras 20 tags p azuis são alteradas para verde

Cuidado ao usar string como função: a função é criada fora de contexto e deve ser usada somente quando você tiver certeza do escopo da variável. Caso contrário, é melhor passar funções em que o escopo é mais intuitivo.





javascript arrays