Como removo um item de matriz no TypeScript?

407

Eu tenho uma matriz que eu criei no TypeScript e tem uma propriedade que eu uso como chave. Se eu tiver essa chave, como posso remover um item dela?

Tim Almond
fonte

Respostas:

641

Da mesma maneira que você faria em JavaScript.

delete myArray[key];

Observe que isso define o elemento para undefined.

Melhor usar a Array.prototype.splicefunção:

const index = myArray.indexOf(key, 0);
if (index > -1) {
   myArray.splice(index, 1);
}
peixe branco
fonte
8
Você pode adicionar um tipo a isso! var index: number = myArray.indexOf(key, 0);
CorayThan
17
@ CorayThan Certamente, seria implicitamente digitado como indexOfretorna a number?
Chris
5
@ Chris Embora seja óbvio neste caso simples, ele pode ajudá-lo a diagnosticar erros mais rapidamente se você definir explicitamente um tipo para cada variável. Você está usando indexmais de uma vez o local e um desses locais ( splice) deseja ver um número ou você receberá um erro. Atualmente, o compilador não pode impedir que você cometa erros por lá.
Jochem Kuijpers
33
@ Blorkfish, é bom mencionar que se você tiver uma lista de objetos, poderá usá-lo var index = myArray.findIndex(x => x.prop==key.prop);.
Francisco Cabral
6
@ Cirelli94 - você está respondendo a um thread mais antigo, mas a resposta para sua pergunta é que a exclusão de um elemento da matriz não altera seu comprimento ou não indexa novamente a matriz. Como matrizes são objetos em JavaScript, delete myArr[2]exclui literalmente a propriedade 2 de myArr, que também é diferente de myArr[2] = undefined. A moral desta história é apenas usar splicepara esta tarefa, porque é uma maneira segura de obter o efeito desejado sem confundir efeitos colaterais.
winglerw28
200

Se a matriz for do tipo de objetos, a maneira mais simples é

let foo_object // Item to remove
this.foo_objects = this.foo_objects.filter(obj => obj !== foo_object);
Malik Shahzad
fonte
20
Isso não remove nada que simplesmente filtra. Se a lista realmente precisar ser modificada, não é esse o caminho.
user573434
6
@ user573434 sim, você está certo, como o nome indica. Mas esta é a abordagem simples no caso em que você deseja remover um objeto em sucesso chamada de API de exclusão etc.
Malik Shahzad
3
Isso funcionou perfeitamente para mim em uma matriz de objetos sem uma propriedade de chave exclusiva. @ user573434 o método filter retorna uma nova matriz sem o objeto filtrado, para que a matriz resultante tenha o objeto removido.
Jason
6
eu acho que, a fim de devolvê-lo como um objeto que você tem que fazer issothis.foo_objects = this.foo_objects.filter(obj => obj !== foo_object)[0];
Roel
11
Isso funciona. basta ler a segunda linha com cuidado. ele faz um filtro com obj! = foo_object. e a atribui à variável original, substituindo assim a matriz original por uma menos o foo_object filtrado. -lo usado com uma variedade de objetos com id deleteById(id: string) { this.data = this.data.filter(d => d.id !== id); }apenas uma palavra de aviso, se os IDs não são exclusivos você irá remover todos com o mesmoid
Markus
74

Com o ES6, você pode usar este código:

removeDocument(doc){
   this.documents.forEach( (item, index) => {
     if(item === doc) this.documents.splice(index,1);
   });
}
Idak
fonte
11
Melhor solução para remover sem alterar referência de matriz E com possibilidade de implementar algorythm igualdade específica
Sid
11
A melhor resposta encontrada
Gvs Akhil
11
Melhor resposta se você estiver usando o ES6 #
Nathan Beck
2
Você também pode usar: this.documents.forEach ((item, index, array) => {if (item === doc) array.splice (index, 1);}); O que pode ser muito mais limpo, especialmente ao trabalhar com matrizes aninhadas.
CGundlach
20

É a minha solução para isso:

onDelete(id: number) {
    this.service.delete(id).then(() => {
        let index = this.documents.findIndex(d => d.id === id); //find index in your array
        this.documents.splice(index, 1);//remove element from array
    });

    event.stopPropagation();
}
Butsaty
fonte
O interessante dessa solução é que ela funcionará mesmo quando a igualdade de objetos não conseguir identificar dois objetos como iguais.
Brad Johnson
18

Você pode usar o splicemétodo em uma matriz para remover os elementos.

por exemplo, se você tiver uma matriz com o nome, arruse o seguinte:

arr.splice(2, 1);

então aqui o elemento com o índice 2 será o ponto de partida e o argumento 2 determinará quantos elementos serão excluídos.

Se você deseja excluir o último elemento da matriz nomeada arr, faça o seguinte:

arr.splice(arr.length-1, 1);

Isso retornará arr com o último elemento excluído.

Exemplo:

var arr = ["orange", "mango", "banana", "sugar", "tea"];
arr.splice(arr.length-1, 1)
console.log(arr); // return ["orange", "mango", "banana", "sugar"]
akash venugopal
fonte
11
Apenas para sua informação, o método de emenda modifica a matriz (portanto, neste caso remove o último item) e retorna os itens removidos, não a matriz em si.
CGundlach
2
Na verdade, deve ser arr.splice (arr.length-1,1) para remover o último elemento.
Steve In CO
15

deixar departamentos é uma matriz. Você deseja remover um item dessa matriz.

departments: string[] = [];

 removeDepartment(name: string): void {
    this.departments = this.departments.filter(item => item != name);
  }
Abdus Salam Azad
fonte
8

Aqui está um liner simples para remover um objeto por propriedade de uma matriz de objetos.

delete this.items[this.items.findIndex(item => item.item_id == item_id)];

ou

this.items = this.items.filter(item => item.item_id !== item.item_id);
Jamie Armour
fonte
11
O problema com a primeira solução é que a exclusão remove o elemento, mas o tamanho da matriz permanece o mesmo de antes da detecção. Na segunda solução, teremos um novo objeto; portanto, se tivermos dependência spme, estaremos perdendo-o. A emenda (que está na resposta superior) não tem esse efeito.
Krystian #
Obrigado por apontar isso. Acho que no meu caso de uso ainda não havia descoberto isso. Bem observado :)
Jamie Armour
5

Responder usando o operador de propagação TypeScript (...)

// Your key
const key = 'two';

// Your array
const arr = [
    'one',
    'two',
    'three'
];

// Get either the index or -1
const index = arr.indexOf(key); // returns 0


// Despite a real index, or -1, use spread operator and Array.prototype.slice()    
const newArray = (index > -1) ? [
    ...arr.slice(0, index),
    ...arr.slice(index + 1)
] : arr;
Joshua Michael Wagoner
fonte
5

Mais uma solução usando o Typecript:

let updatedArray = [];
for (let el of this.oldArray) {
    if (el !== elementToRemove) {
        updated.push(el);
    }
}
this.oldArray = updated;
Sh. Pavel
fonte
Embora isso resolva o problema solicitado, sua execução é cara devido à criação de uma nova matriz e à repetição do original. Fazer esse tipo de operação em uma enorme variedade pode produzir efeitos colaterais indesejáveis como, mais difícil em baterias móveis, longa espera, Jank, etc.
Jessy
1

Use isso, se você precisar remover um determinado objeto de uma matriz e quiser ter certeza do seguinte:

  • a lista não é reinicializada
  • o comprimento da matriz é atualizado corretamente
    const objWithIdToRemove;
    const objIndex = this.objectsArray.findIndex(obj => obj.id === objWithIdToRemove);
    if (objIndex > -1) {
      this.objectsArray.splice(objIndex, 1);
    }
Radu Linu
fonte
0

Só queria adicionar o método de extensão para uma matriz.

interface Array<T> {
      remove(element: T): Array<T>;
    }

    Array.prototype.remove = function (element) {
      const index = this.indexOf(element, 0);
      if (index > -1) {
        return this.splice(index, 1);
      }
      return this;
    };
supernerd
fonte