¿Cómo elimino un elemento de matriz en TypeScript?

407

Tengo una matriz que he creado en TypeScript y tiene una propiedad que uso como clave. Si tengo esa clave, ¿cómo puedo eliminar un elemento?

Tim Almond
fuente

Respuestas:

641

De la misma manera que lo haría en JavaScript.

delete myArray[key];

Tenga en cuenta que esto establece el elemento en undefined.

Mejor usar la Array.prototype.splicefunción:

const index = myArray.indexOf(key, 0);
if (index > -1) {
   myArray.splice(index, 1);
}
blorkfish
fuente
8
¡Puedes agregar un tipo a eso! var index: number = myArray.indexOf(key, 0);
CorayThan
17
@CorayThan Seguramente se escribiría implícitamente como indexOfdevuelve a number?
Chris
55
@Chris Si bien es obvio en este caso simple, puede ayudarlo a diagnosticar errores más rápido si define un tipo para cada variable explícitamente. Ya lo está utilizando indexen más de un lugar y uno de esos lugares ( splice) quiere ver un número o recibirá un error. Actualmente el compilador no puede evitar que cometas errores allí.
Jochem Kuijpers el
33
@blorkfish es bueno mencionar que si tienes una lista de objetos, puedes usarla var index = myArray.findIndex(x => x.prop==key.prop);.
Francisco Cabral
66
@ Cirelli94: está respondiendo a un hilo anterior, pero la respuesta a su pregunta es que eliminar un elemento de matriz no cambia su longitud ni vuelve a indexar la matriz. Debido a que las matrices son objetos en JavaScript, delete myArr[2]literalmente elimina la propiedad 2 de myArr, que también es diferente de myArr[2] = undefined. La moraleja de esta historia es usarla splicepara esta tarea porque es una forma segura de obtener el efecto deseado sin confundir los efectos secundarios.
winglerw28
200

Si la matriz es un tipo de objetos, entonces la forma más simple es

let foo_object // Item to remove
this.foo_objects = this.foo_objects.filter(obj => obj !== foo_object);
Malik Shahzad
fuente
20
Esto no elimina nada, simplemente filtra. Si la lista realmente necesita ser modificada, esta no es la forma.
user573434
66
@ user573434 sí, tiene razón, como su nombre lo indica. Pero este es un enfoque simple en el caso de que desee eliminar un objeto en la eliminación exitosa de la API, etc.
Malik Shahzad
3
Esto funcionó perfectamente para mí en una variedad de objetos sin una propiedad clave única. @ user573434 el método de filtro devuelve una nueva matriz sin el objeto filtrado, por lo que la matriz resultante tiene el objeto eliminado.
Jason
66
Creo que para devolverlo como un objeto tienes que hacer estothis.foo_objects = this.foo_objects.filter(obj => obj !== foo_object)[0];
Roel
1
Esto funciona. solo lea la segunda línea cuidadosamente. él hace un filtro con obj! = foo_object. y lo asigna a la variable original, reemplazando así la matriz original con uno menos el foo_object filtrado. lo usé con una variedad de objetos con identificación deleteById(id: string) { this.data = this.data.filter(d => d.id !== id); }Solo una palabra de advertencia, si los ID no son únicos, los eliminará todos con el mismoid
Markus
74

Con ES6 puede usar este código:

removeDocument(doc){
   this.documents.forEach( (item, index) => {
     if(item === doc) this.documents.splice(index,1);
   });
}
Idak
fuente
1
La mejor solución para eliminar sin cambiar la referencia de matriz Y con la posibilidad de implementar un algoritmo de igualdad específico
Sid
1
La mejor respuesta que he encontrado
Gvs Akhil
1
La mejor respuesta si usa ES6
Nathan Beck
2
También puede usar: this.documents.forEach ((item, index, array) => {if (item === doc) array.splice (index, 1);}); Lo que puede ser mucho más limpio, especialmente cuando se trabaja con matrices anidadas.
CGundlach
20

Es mi solución para eso:

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
fuente
Lo bueno de esta solución es que funcionará incluso cuando la igualdad de objetos no identifique dos objetos como iguales.
Brad Johnson
18

Puedes usar el splice método en una matriz para eliminar los elementos.

por ejemplo, si tiene una matriz con el nombre, arruse lo siguiente:

arr.splice(2, 1);

así que aquí el elemento con el índice 2 será el punto de partida y el argumento 2 determinará cuántos elementos se eliminarán.

Si desea eliminar el último elemento de la matriz nombrada arr, haga esto:

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

Esto devolverá arr con el último elemento eliminado.

Ejemplo:

var arr = ["orange", "mango", "banana", "sugar", "tea"];
arr.splice(arr.length-1, 1)
console.log(arr); // return ["orange", "mango", "banana", "sugar"]
akash venugopal
fuente
1
Solo para su información, el método de empalme modifica la matriz (por lo que en este caso elimina el último elemento) y devuelve los elementos eliminados, no la matriz en sí.
CGundlach
2
En realidad, debería ser arr.splice (arr.length-1,1) para eliminar el último elemento.
Steve In CO
15

dejar departamentos es una matriz. Desea eliminar un elemento de esta matriz.

departments: string[] = [];

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

Aquí hay un revestimiento simple para eliminar un objeto por propiedad de una matriz de objetos.

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

o

this.items = this.items.filter(item => item.item_id !== item.item_id);
Jamie Armor
fuente
1
El problema con la primera solución es que eliminar elimina el elemento, pero el tamaño de la matriz sigue siendo el mismo que antes de la detección. En la segunda solución tendremos un nuevo objeto, por lo que si tenemos dependencia spme, lo estamos perdiendo. Splice (que está en la respuesta superior) no tiene este efecto.
Krystian el
Gracias por señalar eso. Creo que en mi caso de uso aún no lo había descubierto. Bien observado :)
Jamie Armor
5

Responda utilizando el operador de propagación 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 Waggoner
fuente
5

Una solución más usando el mecanografiado:

let updatedArray = [];
for (let el of this.oldArray) {
    if (el !== elementToRemove) {
        updated.push(el);
    }
}
this.oldArray = updated;
Sh. Pavel
fuente
Si bien esto resuelve el problema solicitado, su ejecución es costosa debido a la creación de una nueva matriz y al bucle sobre el original. Hacer este tipo de operación en una gran variedad podría producir efectos secundarios indeseables como, más difícil en las baterías móviles, largas esperas, jank, etc.
Jessy
1

Use esto, si necesita eliminar un objeto determinado de una matriz y desea estar seguro de lo siguiente:

  • la lista no se reinicia
  • la longitud de la matriz se actualiza correctamente
    const objWithIdToRemove;
    const objIndex = this.objectsArray.findIndex(obj => obj.id === objWithIdToRemove);
    if (objIndex > -1) {
      this.objectsArray.splice(objIndex, 1);
    }
Radu Linu
fuente
0

Solo quería agregar un método de extensión para una 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
fuente