splice - remover elemento de um objeto javascript




Como faço para remover um elemento particular de uma matriz em JavaScript? (20)

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.


ES6 e sem mutação: (outubro de 2016)

const removeByIndex = (list, index) =>
  [
    ...list.slice(0, index),
    ...list.slice(index + 1)
  ];

Então :

removeByIndex([33,22,11,44],1) //=> [33,11,44]

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


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

Demasiado velho para responder, mas pode ajudar alguém, fornecendo um predicado em vez de um valor.

NOTA: ele atualizará a matriz fornecida e retornará as linhas afetadas

Uso

var removed = helper.removeOne(arr, row => row.id === 5 );

var removed = helper.remove(arr, row => row.name.startsWith('BMW'));

Definição

var helper = {

    // Remove and return the first occurrence     

    removeOne: function(array, predicate) {
        for (var i = 0; i < array.length; i++) {
            if (predicate(array[i])) {
                return array.splice(i, 1);
            }
        }
    },

    // Remove and return all occurrences  

    remove: function(array, predicate) {
        var removed = [];

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

            if (predicate(array[i])) {
                removed.push(array.splice(i, 1));
                continue;
            }

            i++;                
        }

        return removed;
    }
};

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

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

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.


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

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

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.


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


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

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]

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.


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


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


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.


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




arrays