¿Cómo puedo eliminar un elemento específico de una matriz?

8299

Tengo una serie de números y estoy usando el .push()método para agregarle elementos.

¿Hay una manera simple de eliminar un elemento específico de una matriz?

Estoy buscando el equivalente de algo como:

array.remove(number);

Tengo que usar JavaScript central . Los marcos no están permitidos.

Caminante
fuente

Respuestas:

11897

Encuentre el indexelemento de matriz que desea eliminar con indexOf, y luego elimine ese índice con splice.

El método splice () cambia el contenido de una matriz al eliminar elementos existentes y / o agregar nuevos elementos.

const array = [2, 5, 9];

console.log(array);

const index = array.indexOf(5);
if (index > -1) {
  array.splice(index, 1);
}

// array = [2, 9]
console.log(array); 

El segundo parámetro de splicees el número de elementos a eliminar. Tenga en cuenta que splicemodifica la matriz en su lugar y devuelve una nueva matriz que contiene los elementos que se han eliminado.


Por razones de integridad, aquí hay funciones. Primera función elimina sólo sola ocurrencia (es decir, la eliminación de primer partido de 5de [2,5,9,1,5,8,5]), mientras que segunda función elimina todas las apariciones:

function removeItemOnce(arr, value) { 
    var index = arr.indexOf(value);
    if (index > -1) {
        arr.splice(index, 1);
    }
    return arr;
}

function removeItemAll(arr, value) {
    var i = 0;
    while (i < arr.length) {
        if(arr[i] === value) {
            arr.splice(i, 1);
        } else {
            ++i;
        }
    }
    return arr;
}
Tom Wadley
fuente
15
@ Peter, sí, puede que tengas razón. Este artículo explica más y tiene una solución alternativa para navegadores incompatibles: developer.mozilla.org/en/JavaScript/Reference/Global_Objects/…
Tom Wadley el
33
@AlexandreWiechersVaz Por supuesto, conserva el orden, si no fuera así, no tendría
ningún
15
Puede superar el problema de soporte del navegador IE incluyendo el código que se proporciona aquí
15
@AdrianP. array.indexOf(testValue)en una matriz vacía será -1, y si está probando eso, entonces no hay empalme. Tal vez la respuesta ha cambiado desde entonces.
UpTheCreek
13
IE 7, IE8, IE9, IE10 no son compatibles con Microsoft, ¿por qué los desarrolladores web deberían admitir esos navegadores antiguos? ¡Solo muestre una notificación sobre la actualización del navegador! support.microsoft.com/en-us/lifecycle/…
Lukas Liesis
1268

No sé cómo esperas array.remove(int)comportarte. Hay tres posibilidades que puedo pensar que podrías desear.

Para eliminar un elemento de una matriz en un índice i:

array.splice(i, 1);

Si desea eliminar todos los elementos con valor numberde la matriz:

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

Si solo desea que el elemento en el índice iya no exista, pero no desea que cambien los índices de los otros elementos:

delete array[i];
Peter Olson
fuente
335
delete¡No es la forma correcta de eliminar un elemento de una matriz!
Felix Kling
71
@FelixKling Depende, funciona si quieres hacerlo de modo que array.hasOwnProperty(i)regrese falsey que el elemento en esa posición regrese undefined. Pero admito que no es algo muy común querer hacer.
Peter Olson
88
deleteno actualizará la longitud de la matriz ni borrará realmente el elemento, solo lo reemplazará con el valor especial undefined.
diosney
34
@diosney No sé a qué te refieres cuando dices que realmente no borra el elemento. Además, hace más que simplemente reemplazar el valor en ese índice con undefined: elimina tanto el índice como el valor de la matriz, es decir delete array[0], después , "0" in arraydevolverá falso.
Peter Olson
17
@GrantGryczan Lo siento, no estoy de acuerdo. No veo la necesidad de que esto se elimine. El texto anterior explica claramente lo que hace y ayuda a las personas que no saben qué deletehacer a entender por qué no funciona como esperan.
Peter Olson
1207

Editado en octubre de 2016

  • Hazlo simple, intuitivo y explícito ( navaja de Occam )
  • Hazlo inmutable (la matriz original permanece sin cambios)
  • Hágalo con las funciones estándar de JavaScript, si su navegador no las admite: use polyfill

En este ejemplo de código, uso la función "array.filter (...)" para eliminar elementos no deseados de una matriz. Esta función no cambia la matriz original y crea una nueva. Si su navegador no es compatible con esta función (por ejemplo, Internet Explorer antes de la versión 9 o Firefox antes de la versión 1.5), considere usar el polyfill de filtro de Mozilla .

Eliminando elemento (código ECMA-262 Edición 5, también conocido como JavaScript de estilo antiguo)

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 ]

Eliminando elemento (código ECMAScript 6)

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 La sintaxis de la función de flecha ECMAScript 6 "() => {}" no es compatible en absoluto con Internet Explorer, Chrome antes de la versión 45, Firefox antes de la versión 22 y Safari antes de la versión 10. Para usar la sintaxis de ECMAScript 6 en navegadores antiguos, puede usar BabelJS .


Eliminar varios elementos (código ECMAScript 7)

Una ventaja adicional de este método es que puede eliminar varios elementos

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: la función "array.includes (...)" no es compatible en absoluto con Internet Explorer, Chrome antes de la versión 47, Firefox antes de la versión 43, Safari antes de la versión 9 y Edge antes de la versión 14, así que aquí hay polyfill de Mozilla .

Eliminar múltiples elementos (en el futuro, tal vez)

Si alguna vez se acepta la propuesta de "esta sintaxis vinculante" , podrá hacer esto:

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

Pruébalo tú mismo en BabelJS :)

Referencia

ujeenator
fuente
66
pero, a veces, queremos eliminar el elemento de la matriz original (no inmutable), por ejemplo, la matriz utilizada en la directiva Angular 2 * ngFor
Ravinder Payal
43
Mejor que la solución aceptada porque no supone una sola aparición de un partido y la inmutabilidad es preferible
Greg
13
filter¿debe ser mucho más lento para una gran variedad?
Nathan
3
¿Cuál es el punto de inmutabilidad mencionado si usó la asignación de la misma variable en sus ejemplos? :)
mench
12
Esta es una respuesta genial. Splice es una función especializada para mutar, no filtrar. filterpuede tener un rendimiento más lento, pero es un código más seguro y mejor. Además, puede filtrar por índice especificando un segundo argumento en la lambda:arr.filter((x,i)=>i!==2)
Mateo
449

Depende de si quieres mantener un espacio vacío o no.

Si desea un espacio vacío, eliminar está bien:

delete array[index];

Si no lo hace, debe usar el método de empalme :

array.splice(index, 1);

Y si necesita el valor de ese elemento, puede almacenar el elemento de la matriz devuelta:

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

En caso de que desee hacerlo en algún orden, puede usarlo array.pop()para el último o array.shift()para el primero (y ambos devuelven el valor del artículo también).

Y si no conoce el índice del elemento, puede usarlo array.indexOf(item)para obtenerlo ( if()para obtener un elemento o while()para obtener todos). array.indexOf(item)devuelve el índice o -1 si no se encuentra. 

xavierm02
fuente
25
delete¡No es la forma correcta de eliminar un elemento de una matriz!
Progo
16
Si desea "vaciar un espacio", use array[index] = undefined;. El uso deletedestruirá la optimización.
Bergi
44
@Jakub muy buen comentario porque para entender que perdí mucho tiempo y pensé que mi código de aplicación está de alguna manera roto ...
Pascal
El último párrafo con la explicación de lo que obtienes de indexOf fue realmente útil
A. D'Alfonso
277

Un amigo tenía problemas en Internet Explorer 8 y me mostró lo que hizo. Le dije que estaba mal, y él me dijo que tenía la respuesta aquí. La respuesta principal actual no funcionará en todos los navegadores (por ejemplo, Internet Explorer 8) y solo eliminará la primera aparición del elemento.

Eliminar TODAS las instancias de una matriz

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

Recorre la matriz hacia atrás (ya que los índices y la longitud cambiarán a medida que se eliminan los elementos) y elimina el elemento si se encuentra. Funciona en todos los navegadores.

Ben Lesh
fuente
11
@sroes no debería ser porque el ciclo comienza en i = arr.length -1o i--es igual al índice máximo. arr.lengthes solo un valor inicial para i. i--siempre será verdadero (y se reducirá en 1 en cada ciclo op) hasta que sea igual 0(un valor falso) y el ciclo se detendrá.
gmajivu
1
La segunda función es bastante ineficiente. En cada iteración, "indexOf" comenzará la búsqueda desde el principio de la matriz.
ujeenator
3
@AmberdeBlack, en una colección con más de 1 aparición de elemento , es mucho mejor llamar al método de filtroarr.filter(function (el) { return el !== item }) , evitando la necesidad de mutar la matriz varias veces. Esto consume un poco más de memoria, pero funciona de manera mucho más eficiente, ya que hay menos trabajo por hacer.
Eugene Kuzmenko
1
@AlJey, solo está disponible en IE9 +. Todavía hay una posibilidad de que no funcione.
ujeenator
1
Esta respuesta funcionó para mí porque necesitaba eliminar varios elementos, pero no en ningún orden en particular. La progresión hacia atrás del bucle for aquí maneja la eliminación de elementos de la matriz perfectamente.
mintedsky
172

Hay dos enfoques principales:

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

  2. eliminar :delete anArray[index];

Tenga cuidado cuando use eliminar para una matriz. Es bueno para eliminar atributos de objetos, pero no tan bueno para matrices. Es mejor usarlo splicepara matrices.

Tenga en cuenta que cuando usa deleteuna matriz puede obtener resultados incorrectos anArray.length. En otras palabras, deleteeliminaría el elemento, pero no actualizaría el valor de la propiedad de longitud.

También puede esperar tener agujeros en los números de índice después de usar eliminar, por ejemplo, podría terminar teniendo los índices 1, 3, 4, 8, 9 y 11 y la longitud que tenía antes de usar eliminar. En ese caso, todos los forbucles indexados se bloquearían, ya que los índices ya no son secuenciales.

Si se ve obligado a usarlo deletepor algún motivo, debe usar for eachbucles cuando necesite recorrer los arreglos. De hecho, evite siempre usar forbucles indexados , si es posible. De esa forma, el código sería más robusto y menos propenso a problemas con los índices.

Sasa
fuente
144
Array.prototype.remByVal = function(val) {
    for (var i = 0; i < this.length; i++) {
        if (this[i] === val) {
            this.splice(i, 1);
            i--;
        }
    }
    return this;
}
//Call like
[1, 2, 3, 4].remByVal(3);

Array.prototype.remByVal = function(val) {
    for (var i = 0; i < this.length; i++) {
        if (this[i] === val) {
            this.splice(i, 1);
            i--;
        }
    }
    return this;
}

var rooms = ['hello', 'something']

rooms = rooms.remByVal('hello')

console.log(rooms)

Zirak
fuente
14
No soy un gran admirador de este enfoque. Si terminas usando diferentes bibliotecas o marcos, pueden terminar en conflicto entre sí.
Charlie Kilian el
10
Mala idea, vea esta publicación: stackoverflow.com/questions/948358/array-prototype-problem
MMeah
10
Si está haciendo un for inen una matriz, ya tiene un problema.
Zirak
2
Si lo hace for inen matrices, ya tiene problemas más grandes.
Rainb
use Object.defineProperty stackoverflow.com/a/35518127/3779853 y listo.
phil294
105

No hay necesidad de usar indexOfo splice. Sin embargo, funciona mejor si solo desea eliminar una aparición de un elemento.

Buscar y mover (mover):

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

Uso indexOfy splice(indexof):

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

Usar solo splice(empalme):

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

Tiempos de ejecución en nodejs para una matriz con 1000 elementos (promedio de más de 10000 ejecuciones):

indexof es aproximadamente 10 veces más lento que el movimiento . Incluso si mejorado mediante la eliminación de la llamada a la indexOfde empalme se realiza mucho peor que el movimiento .

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
slosd
fuente
55
Parece que el método 'mover' presentado aquí debería funcionar en todos los navegadores, y también evita crear una matriz adicional; La mayoría de las otras soluciones aquí tienen uno o ambos problemas. Creo que este merece muchos más votos, incluso si no parece "bonito".
sockmonk
73

Esto proporciona un predicado en lugar de un valor.

NOTA: actualizará la matriz dada y devolverá las filas afectadas.

Uso

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

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

Definición

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;
    }
};
amd
fuente
No sé si necesita la comprobación -1 (i> -1). Además, creo que estas funciones actúan más como filtro que eliminar. Si pasa row.id === 5, dará como resultado una matriz con solo id 5, por lo que está haciendo lo contrario de eliminar. Se vería bien en ES2015: var result = ArrayHelper.remove (myArray, row => row.id === 5);
Qué sería genial
@WhatWouldBeCool esta función modifica la matriz original y devuelve el elemento eliminado en lugar de copiar el resultado a una nueva matriz
amd
68

Puede hacerlo fácilmente con el método de filtro :

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

Esto elimina todos los elementos de la matriz y también funciona más rápido que una combinación de slicey indexOf.

Salvador Dalí
fuente
3
¿Tienes una fuente de que esto es más rápido?
user3711421
2
Buena solución Pero como usted señala, pero es importante hacer la calvicie, no produce el mismo resultado que cortar e indexar, ya que eliminará todas las apariciones de 1
user3711421
1
@ user3711421 esto se debe a que solo cortar e indexar no hace lo que quiere "para eliminar un elemento específico". Elimina el elemento solo una vez, elimina un elemento específico sin importar cuántos de ellos tenga
Salvador Dali
66

John Resig publicó una buena implementación :

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

Si no desea extender un objeto global, puede hacer algo como lo siguiente:

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

Pero la razón principal por la que estoy publicando esto es para advertir a los usuarios contra la implementación alternativa sugerida en los comentarios en esa página (14 de diciembre 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;
};

Al principio parece funcionar bien, pero a través de un proceso doloroso descubrí que falla al intentar eliminar el penúltimo elemento de una matriz. Por ejemplo, si tiene una matriz de 10 elementos e intenta eliminar el noveno elemento con esto:

myArray.remove(8);

Terminas con una matriz de 8 elementos. No sé por qué, pero he confirmado que la implementación original de John no tiene este problema.

Roger
fuente
Acabo de aprender por las malas por qué es una buena idea usar Object.prototype.hasOwnPropertysiempre ¬¬
Davi Fiamenghi
64

Underscore.js se puede usar para resolver problemas con varios navegadores. Utiliza métodos de navegador integrados si están presentes. Si están ausentes, como en el caso de versiones anteriores de Internet Explorer, utiliza sus propios métodos personalizados.

Un ejemplo simple para eliminar elementos de la matriz (del sitio web):

_.without([1, 2, 1, 0, 3, 1, 4], 0, 1); // => [2, 3, 4]
vatsal
fuente
aunque elegante y conciso, OP mencionó claramente solo JS núcleo
EigenFool
64

Puedes usar ES6. Por ejemplo, para eliminar el valor '3' en este caso:

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

Salida:

["1", "2", "4", "5", "6"]
rajat44
fuente
44
Esta respuesta es buena porque crea una copia de la matriz original, en lugar de modificar el original directamente.
Claudio Holanda
Nota: Array.prototype.filter es ECMAScript 5.1 (No IE8). para soluciones más específicas: stackoverflow.com/a/54390552/8958729
Chang
54

Si desea una nueva matriz con las posiciones eliminadas eliminadas, siempre puede eliminar el elemento específico y filtrar la matriz. Es posible que necesite una extensión del objeto de matriz para los navegadores que no implementan el método de filtro, pero a largo plazo es más fácil ya que todo lo que hace es esto:

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

Debería mostrar [1, 2, 3, 4, 6].

Loupax
fuente
45

Mira este código. Funciona en todos los principales navegadores .

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

Llamar a esta función

remove_item(array,value);
Ekramul Hoque
fuente
44
@RolandIllig Excepto el uso de un for inbucle y el hecho de que el script podría detenerse antes, devolviendo el resultado directamente del bucle. Los votos a favor son razonables;)
yckart
1
Este es un enfoque excelente para matrices pequeñas. Funciona en todos los navegadores, utiliza un código mínimo e intuitivo y sin marcos de trabajo, cuñas o polyfills adicionales complejos.
Beejor
También debería reiterar el comentario de yckart que for( i = 0; i < arr.length; i++ )sería un mejor enfoque, ya que conserva los índices exactos en comparación con el orden en que el navegador decida almacenar los elementos (con for in). Hacerlo también le permite obtener el índice de matriz de un valor si lo necesita.
Beejor
41

Puede usar lodash _.pull ( mutate array), _.pullAt ( mutate array) o _.without (no mutate 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']
Chun Yang
fuente
2
Ese no es el núcleo JS como lo solicitó el OP, ¿verdad?
un usuario no descripto
12
@ some-non-descript-user Tiene razón. Pero muchos usuarios como yo vienen aquí buscando una respuesta general, no solo para el OP.
Chun Yang el
@ChunYang Tienes toda la razón. Ya estoy usando lodash, ¿por qué no solo usarlo si ahorra tiempo?
int-i
38

ES6 y sin mutación: (octubre de 2016)

const removeByIndex = (list, index) =>
      [
        ...list.slice(0, index),
        ...list.slice(index + 1)
      ];
         
output = removeByIndex([33,22,11,44],1) //=> [33,11,44]
      
console.log(output)

Abdennour TOUMI
fuente
¿Por qué no solo usar filterentonces? array.filter((_, index) => index !== removedIndex);.
user4642212
@ user4642212 tienes razón! Además, me gustó el guión bajo del estilo Golang
Abdennour TOUMI
36

La eliminación de un elemento / cadena particular de una matriz se puede hacer de una sola línea:

theArray.splice(theArray.indexOf("stringToRemoveFromArray"), 1);

dónde:

theArray : la matriz de la que desea eliminar algo en particular

stringToRemoveFromArray : la cadena que desea eliminar y 1 es la cantidad de elementos que desea eliminar.

NOTA : Si "stringToRemoveFromArray" no se encuentra en su matriz, esto eliminará el último elemento de la matriz.

Siempre es una buena práctica verificar si el elemento existe primero en su matriz, antes de eliminarlo.

if (theArray.indexOf("stringToRemoveFromArray") >= 0){
   theArray.splice(theArray.indexOf("stringToRemoveFromArray"), 1);
}

Si tiene acceso a las nuevas versiones de Ecmascript en las computadoras de su cliente (ADVERTENCIA, puede no funcionar en estaciones más antiguas):

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

Donde '3' es el valor que desea eliminar de la matriz. La matriz se convertiría en:['1','2','4','5','6']

Max Alexander Hanna
fuente
Esta es la respuesta que funcionó para mí al intentar actualizar una matriz basada en la alternancia de botones de radio.
jdavid05
44
Tenga cuidado, si "stringToRemoveFromArray"no está ubicado en su matriz, esto eliminará el último elemento de la matriz.
Fusion el
35

Aquí hay algunas maneras de eliminar un elemento de una matriz usando JavaScript .

Todos los métodos descritos no mutan la matriz original y, en cambio, crean una nueva.

Si conoce el índice de un artículo

Supongamos que tiene una matriz y desea eliminar un elemento en posición i.

Un método es usar slice():

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

console.log(filteredItems)

slice()crea una nueva matriz con los índices que recibe. Simplemente creamos una nueva matriz, desde el inicio hasta el índice que queremos eliminar, y concatenamos otra matriz desde la primera posición que sigue a la que eliminamos hasta el final de la matriz.

Si sabes el valor

En este caso, una buena opción es usar filter(), que ofrece un enfoque más declarativo :

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

console.log(filteredItems)

Esto utiliza las funciones de flecha ES6. Puede usar las funciones tradicionales para admitir navegadores antiguos:

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

console.log(filteredItems)

o puede usar Babel y volver a compilar el código ES6 a ES5 para que sea más digerible para los navegadores antiguos, y aún así escribir JavaScript moderno en su código.

Eliminar múltiples elementos

¿Qué sucede si, en lugar de un solo elemento, desea eliminar muchos elementos?

Encontremos la solución más simple.

Por índice

Simplemente puede crear una función y eliminar elementos en serie:

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

Puede buscar la inclusión dentro de la función de devolución de llamada:

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 mutar la matriz original.

splice()(no debe confundirse con slice()) muta la matriz original y debe evitarse.

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

Flavio Copes
fuente
34

OK, por ejemplo, tienes la siguiente matriz:

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

Y queremos eliminar el número 4. Simplemente puede usar el siguiente código:

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

Si está reutilizando esta función, escriba una función reutilizable que se adjuntará a la función de matriz nativa como se muestra a continuación:

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

Pero, ¿qué tal si tiene la siguiente matriz en su lugar con algunos [5] s en la matriz?

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

Necesitamos un bucle para verificarlos todos, pero una manera más fácil y eficiente es usar funciones de JavaScript incorporadas, por lo que escribimos una función que usa un filtro como el siguiente:

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]

También hay bibliotecas de terceros que lo ayudan a hacer esto, como Lodash o Underscore. Para obtener más información, mire lodash _.pull, _.pullAt o _.without.

Alireza
fuente
Hay un pequeño error tipográfico. Por favor corrige. this.splice(num.indexOf(x), 1);=>this.splice(this.indexOf(x), 1);
TheGwa
No aumente las funciones integradas (adjunte funciones a Array.prototype) en JavaScript. Esto es ampliamente considerado como una mala práctica.
aikeru
Estoy de acuerdo en que no es lo mejor que se puede hacer en el mundo, pero en este caso, ¿cómo podría pasarlo a la función?
Alireza
Deberías consultar el índice. Si index = -1, splice (-1,1) eliminará el último elemento
Richard Chan
29

Soy bastante nuevo en JavaScript y necesitaba esta funcionalidad. Simplemente escribí esto:

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

Entonces cuando quiero usarlo:

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

Salida: como se esperaba. ["item1", "item1"]

Es posible que tenga necesidades diferentes que yo, por lo que puede modificarlo fácilmente para adaptarlo a ellas. Espero que esto ayude a alguien.

sofiax
fuente
1
Esto tendrá un comportamiento terrible si su matriz es realmente larga y hay varias instancias del elemento en ella. El método de matriz indexOf comenzará al principio cada vez, por lo que su costo será O (n ^ 2).
Zag
@Zag: Tiene un nombre: Algoritmo de Shlemiel el Pintor
Peter Mortensen el
27

Si tiene objetos complejos en la matriz, ¿puede usar filtros? En situaciones donde $ .inArray o array.splice no es tan fácil de usar. Especialmente si los objetos son quizás poco profundos en la matriz.

Por ejemplo, si tiene un objeto con un campo Id y desea eliminar el objeto de una matriz:

this.array = this.array.filter(function(element, i) {
    return element.id !== idToRemove;
});
flurdy
fuente
Así es como me gusta hacerlo. El uso de una función de flecha puede ser de una sola línea. Tengo curiosidad sobre el rendimiento. Tampoco vale nada que esto reemplace la matriz. Cualquier código con una referencia a la matriz anterior no notará el cambio.
joeytwiddle
27

Quiero responder basado en ECMAScript 6 . Supongamos que tiene una matriz como la siguiente:

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

Si desea eliminar en un índice especial como 2, escriba el siguiente código:

arr.splice(2, 1); //=> arr became [1,2,4]

Pero si desea eliminar un elemento especial como 3y no conoce su índice, haga lo siguiente:

arr = arr.filter(e => e !== 3); //=> arr became [1,2,4]

Sugerencia : utilice una función de flecha para la devolución de llamada del filtro a menos que obtenga una matriz vacía.

AmerllicA
fuente
25

Actualización: este método se recomienda solo si no puede usar ECMAScript 2015 (anteriormente conocido como ES6). Si puede usarlo, otras respuestas aquí proporcionan implementaciones mucho más ordenadas.


Esta esencia aquí resolverá su problema y también elimina todas las apariciones del argumento en lugar de solo 1 (o un 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]
zykadelic
fuente
25

Actuación

Hoy (09-12-2019) realizo pruebas de rendimiento en macOS v10.13.6 (High Sierra) para las soluciones elegidas. Muestro delete(A), pero no lo uso en comparación con otros métodos, porque dejó un espacio vacío en la matriz.

Las conclusiones

  • la solución más rápida es array.splice (C) (excepto Safari para arreglos pequeños donde tiene la segunda vez)
  • para grandes matrices, array.slice+splice(H) es la solución inmutable más rápida para Firefox y Safari;Array.from(B) es el más rápido en Chrome
  • las soluciones mutables suelen ser 1.5x-6x más rápidas que las inmutables
  • para tablas pequeñas en Safari, sorprendentemente la solución mutable (C) es más lenta que la solución inmutable (G)

Detalles

En las pruebas elimino el elemento medio de la matriz de diferentes maneras. Las soluciones A, C están en su lugar. Las soluciones B, D, E, F, G, H son inmutables.

Resultados para matriz con 10 elementos

Ingrese la descripción de la imagen aquí

En Chrome, la array.splice(C) es la solución más rápida en el lugar. La array.filter(D) es la solución inmutable más rápida. El más lento es array.slice(F). Puede realizar la prueba en su máquina aquí .

Resultados para matriz con 1.000.000 de elementos.

Ingrese la descripción de la imagen aquí

En Chrome, la array.splice(C) es la solución más rápida en el lugar (la delete(C) es similar rápidamente, pero dejó una ranura vacía en la matriz (por lo que no realiza una 'eliminación completa')). La array.slice-splice(H) es la solución inmutable más rápida. El más lento es array.filter(D y E). Puede realizar la prueba en su máquina aquí .

Comparación para navegadores: Chrome v78.0.0, Safari v13.0.4 y Firefox v71.0.0

Ingrese la descripción de la imagen aquí

Kamil Kiełczewski
fuente
24

Nunca debe mutar su matriz. Como esto va en contra del patrón de programación funcional. Puede crear una nueva matriz sin hacer referencia a la matriz de la que desea cambiar los datos utilizando el método ECMAScript 6 filter;

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

Supongamos que desea eliminar 5de la matriz, simplemente puede hacerlo así:

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

Esto le dará una nueva matriz sin el valor que desea eliminar. Entonces el resultado será:

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

Para una mejor comprensión, puede leer la documentación de MDN en Array.filter .

Adeel Imran
fuente
21

Un enfoque más moderno, ECMAScript 2015 (anteriormente conocido como Harmony o ES 6). Dado:

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

Entonces:

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

Flexible:

[1, 2, 4]

Puede usar Babel y un servicio polyfill para asegurarse de que esto sea compatible con todos los navegadores.

bjfletcher
fuente
44
Tenga en cuenta que .filterdevuelve una nueva matriz, que no es exactamente lo mismo que eliminar el elemento de la misma matriz. El beneficio de este enfoque es que puede encadenar métodos de matriz juntos. por ejemplo:[1,2,3].filter(n => n%2).map(n => n*n) === [ 1, 9 ]
CodeOcelot
Genial, si tengo 600k elementos en la matriz y quiero eliminar los primeros 50k, ¿te imaginas esa lentitud? Esto no es una solución, hay necesidad de una función que simplemente elimine elementos y no devuelva nada.
dev1223
@Seraph Para eso, probablemente quieras usar spliceo slice.
bjfletcher
@bjfletcher Eso es aún mejor, en proceso de eliminación, solo asigna 50K elementos y tíralos a alguna parte. (con elementos de corte 550K, pero sin tirarlos desde la ventana).
dev1223
Prefiero la respuesta de bjfletcher, que podría ser tan breve como items= items.filter(x=>x!=3). Además, el OP no estableció ningún requisito para un gran conjunto de datos.
corre el
21

Tiene de 1 a 9 en la matriz y desea eliminar 5. Use el siguiente 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);


Si quieres múltiples valores. Ejemplo: - 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, 1,7 and 8 removed", newNumberArray);


Si desea eliminar un valor de matriz en una matriz. Ejemplo: [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);

Incluye navegador compatible es enlace .

Thilina Sampath
fuente
19

Sé que ya hay muchas respuestas, pero muchas de ellas parecen complicar demasiado el problema. Aquí hay una manera simple y recursiva de eliminar todas las instancias de una clave: se llama a sí mismo hasta que no se encuentra el índice. Sí, solo funciona en navegadores indexOf, pero es simple y se puede rellenar fácilmente.

Función independiente

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

    if(index === -1) return;

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

Método de prototipo

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

    if(index === -1) return;

    this.splice(index, 1);
    this.removeAll(key);
}
wharding28
fuente
Solo una nota, 1 advertencia con este método es el potencial de desbordamientos de pila. A menos que esté trabajando con matrices masivas, no debería tener un problema.
wharding28
¿Pero por qué un retorno en el medio? Es efectivamente una declaración goto.
Peter Mortensen
18

Puede hacer un bucle hacia atrás para asegurarse de no arruinar los índices, si hay varias instancias del 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);
}

Demo en vivo

Jeff Noel
fuente