Eliminar elemento de una matriz en JavaScript

En JavaScript, y al igual que muchos otros lenguajes, en algún momento probablemente necesitará eliminar un elemento de una matriz. Dependiendo de su caso de uso, esto ...

En JavaScript, y al igual que muchos otros lenguajes, en algún momento probablemente necesitará eliminar un elemento de una matriz. Dependiendo de su caso de uso, esto podría ser tan fácil como usar los comandos integrados shift() o pop(), pero eso solo funciona si el elemento está al principio o al final de la matriz, respectivamente. Muchos casos de uso requerirán que admita la eliminación de un elemento de una ubicación arbitraria en la matriz, que es lo que cubriremos aquí.

También explicaré cómo lograr esto de otras maneras, como con el uso de bibliotecas de utilidades que lo manejarán por usted, o si tiene que admitir navegadores más antiguos como IE 8.

JavaScript estándar

Para eliminar un elemento en particular de una matriz en JavaScript, primero querremos encontrar la ubicación del elemento y luego eliminarlo.

Se puede encontrar la ubicación por valor con el método indexOf(), que devuelve el índice de la primera aparición del valor dado, o -1 si no está en la matriz.

Usando este valor de índice, querremos eliminar el elemento, lo que podemos hacer con el método splice().

1
2
3
4
5
6
function removeElement(array, elem) {
    var index = array.indexOf(elem);
    if (index > -1) {
        array.splice(index, 1);
    }
}

Entonces, si indexOf y splice son los únicos dos métodos que necesitamos para lograr esto, entonces, ¿para qué sirve la instrucción if? Al verificar si el índice es mayor que -1, estamos verificando que el elemento esté realmente presente en la matriz. Si no fue así, y index es -1, entonces usar este valor en splice eliminará el último elemento en la matriz, que no es lo que queremos.

Tenga en cuenta que esto solo elimina la primera aparición del elemento dado. Vea el siguiente ejemplo para ilustrar esto:

1
2
3
4
5
6
var arr = [1, 2, 3, 3, 4, 5];
removeElement(arr, 3);
console.log(arr);

// Output:
// [ 1, 2, 3, 4, 5 ]

Observe que el segundo '3' todavía está presente.

Si queremos eliminar todas las instancias del elemento especificado, podemos lograrlo con un ciclo while en lugar de la instrucción if:

1
2
3
4
5
6
7
function removeAllElements(array, elem) {
    var index = array.indexOf(elem);
    while (index > -1) {
        array.splice(index, 1);
        index = array.indexOf(elem);
    }
}

Ahora, ejecutando el mismo código de ejemplo anterior, obtenemos lo siguiente:

1
2
3
4
5
6
var arr = [1, 2, 3, 3, 4, 5];
removeAllElements(arr, 3);
console.log(arr);

// Output:
// [ 1, 2, 4, 5 ]

Como puede ver, ambos elementos '3' ahora se eliminan de la matriz.

Bibliotecas

Dado que este es un caso de uso tan común, la mayoría (si no todas) de las bibliotecas de utilidades tienen una función para eliminar elementos de una matriz.

Lodash

Para eliminar un elemento, Lodash tiene el método remove(). Si tiene un caso de uso bastante simple, solo desea eliminar un elemento primitivo (como un número), entonces esta función probablemente sea excesiva para usted, ya que necesita pasar una función que determine si el elemento coincide con sus criterios.

Entonces, por ejemplo, así es como eliminaría el número 3:

1
2
3
4
5
6
7
8
var arr = [1, 2, 3, 3, 4, 5];
_.remove(arr, function(e) {
    return e === 3;
});
console.log(arr);

// Output:
// [ 1, 2, 4, 5 ]

Observe que ha eliminado todas las instancias de 3, que es el comportamiento predeterminado.

Sin embargo, este método es más útil cuando se eliminan elementos más complejos, como objetos. Por ejemplo, tal vez desee eliminar todos los objetos "personas" de una matriz si tienen menos de 21 años:

 1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
12
13
var people = [
    {name: 'Billy', age: 22},
    {name: 'Sally', age: 19},
    {name: 'Timmy', age: 29},
    {name: 'Tammy', age: 15}
];
_.remove(people, function(e) {
    return e.age < 21
});
console.log(people);

// Output
// [ { name: 'Billy', age: 22 }, { name: 'Timmy', age: 29 } ]

Funciona un poco como el método filter, excepto que elimina los elementos de la matriz que pasa y luego devuelve una matriz de los elementos eliminados del propio método.

Guion bajo

La biblioteca de utilidades de subrayado tiene un método similar al de Lodash, llamado rechazar. Funciona de manera muy similar, excepto por una diferencia notable. La matriz resultante se devuelve desde el método y la matriz que le pasa permanece sin cambios.

Consulte el siguiente código para ver un ejemplo:

 1
 2
 3
 4
 5
 6
 7
 8
 9
10
var arr = [1, 2, 3, 3, 4, 5];
var ret = _.reject(arr, function(e) {
    return e === 3;
});
console.log(arr);
console.log(ret);

// Output:
// [ 1, 2, 3, 3, 4, 5 ]
// [ 1, 2, 4, 5 ]

Nuevamente, al igual que el método remove de Lodash, el método reject es más adecuado para casos más complejos, como eliminar objetos o grupos de elementos.

Compatibilidad con Internet Explorer

Si su proyecto requiere que admita versiones antiguas de Internet Explorer, específicamente IE 8 en este caso, entonces el método indexOf() no funcionará para usted ya que no es compatible con esta versión de IE.

Para lidiar con esto, una solución es calzar el método, como se muestra en esta respuesta de desbordamiento de pila:

 1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
12
13
14
15
16
17
18
19
20
21
22
if (!Array.prototype.indexOf)
{
  Array.prototype.indexOf = function(elt /*, from*/)
  {
    var len = this.length >>> 0;

    var from = Number(arguments[1]) || 0;
    from = (from < 0)
         ? Math.ceil(from)
         : Math.floor(from);
    if (from < 0)
      from += len;

    for (; from < len; from++)
    {
      if (from in this &&
          this[from] === elt)
        return from;
    }
    return -1;
  };
}

Según la publicación de SO, esta es la implementación de indexOf de MDN, utilizada en Firefox/SpiderMonkey.

Otra opción sería usar el método $.inArray() de jQuery:

1
2
3
4
5
6
var arr = [1, 2, 3, 3, 4, 5];
var idx = $.inArray(3, arr);
console.log(idx);

// Output:
// 2

Esto es más o menos equivalente a indexOf, que luego se puede usar para escribir el método removeElement como se muestra en la primera sección de este artículo. rtículo.