objetos - eliminar un elemento especifico de un array javascript




¿Cómo elimino un elemento en particular de una matriz en JavaScript? (20)

ES6 y sin mutación: (octubre 2016)

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

Entonces :

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

Tengo una matriz de enteros y estoy usando el método .push() para agregarle elementos.

¿Hay una forma sencilla de eliminar un elemento específico de una matriz? El equivalente de algo como array.remove(int); .

Tengo que usar JavaScript central , no se permiten marcos.


Editado el 2016 octubre

  • Hágalo simple, intuitivo y explícito ( https://en.wikipedia.org/wiki/Occam%27s_razor )
  • Hazlo inmutable (la matriz original permanece sin cambios)
  • Hágalo con las funciones estándar de JS, 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 la matriz, esta función no cambia la matriz original y crea una nueva. Si su navegador no admite esta función (por ejemplo, IE antes de la versión 9, o Firefox antes de la versión 1.5), considere usar el filtro de polietileno de Mozilla .

Eliminando artículo (ECMA-262 Edición 5 código aka 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 ]

Eliminando artículo (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 "() => {}" la sintaxis de la función de flecha no se admite en absoluto, Chrome antes de la versión 45, Firefox antes de la versión 22, Safari antes de la versión 10. Para usar la sintaxis de ES2015 en navegadores antiguos, puede usar BabelJS

Eliminación de múltiples elementos (código ES2016)

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 ]

La función "array.includes (...)" IMPORTANTE no es compatible con IE, 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í está el polyfill de Mozilla

Eliminación de varios elementos (vanguardista experimental JavaScript 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 ]

Pruébalo tú mismo en BabelJS :)

Referencia


Demasiado viejo para responder, pero puede ayudar a alguien, proporcionando 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;
    }
};

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

Si quieres una ranura vacía, eliminar está bien:

delete array[ index ];

Si no lo hace, debe utilizar el método de splice :

array.splice( index, 1 );

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

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

En caso de que quiera hacerlo en algún orden, puede usar array.pop() para el último o array.shift() para el primero (y ambos también devuelven el valor del elemento).

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


Encuentre el index del elemento de la matriz que desea eliminar, luego elimine ese índice con splice .

El método splice () cambia el contenido de una matriz eliminando elementos existentes y / o agregando nuevos 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);

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

Nota : el soporte del navegador para indexOf es limitado; No es compatible con Internet Explorer 7 y 8.

Si necesita indexOf en un navegador no compatible, intente con el siguiente polyfill . Encuentra más información acerca de este polyfill aquí .

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

Hay dos enfoques principales:

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

  2. delete : delete anArray[index];

Tenga cuidado cuando use eliminar para una matriz. Es bueno para eliminar atributos de objetos pero no tan bueno para arreglos. Es mejor usar splice para matrices.

Tenga en cuenta que cuando usa delete para una matriz, puede obtener resultados incorrectos para anArray.length . En otras palabras, delete eliminarí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 índices de 1,3,4,8,9,11 y la longitud que tenía antes de usar eliminar. En ese caso, todos los indexados for bucles se bloquearían, ya que los índices ya no son secuenciales.

Si se ve obligado a usar delete por algún motivo, entonces debe usarlo for each bucle cuando necesite recorrer los arreglos. De hecho, siempre evite usar indexados para bucles, si es posible. De esa manera, el código sería más robusto y menos propenso a problemas con los índices.


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

Encuentra y mueve (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;
}

Utilice indexOf y splice (indexof):

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

Utilice sólo 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 matriz con 1000 elementos (promedio de más de 10000 ejecuciones):

El índice es aproximadamente 10 veces más lento que el movimiento . Incluso si se mejora al eliminar la llamada a indexOf en empalme, se realiza mucho peor 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

No sé cómo espera que se array.remove(int) . Hay tres posibilidades en las que puedo pensar que podrías estar deseando.

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

array.splice(i, 1);

Si desea eliminar todos los elementos con number valor de 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 i ya no exista, pero no desea que cambien los índices de los otros elementos:

delete array[i];

Puede utilizar lodash _.pull (matriz de _.pullAt ), _.pullAt (matriz de _.without ) o _.without (no muta la matriz),

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

Puedes hacerlo fácilmente con el 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) );

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


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

Debe mostrar [1, 2, 3, 4, 6]


Si tienes objetos complejos en la matriz puedes 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 de identificación y desea que el objeto se elimine de una matriz:

this.array = this.array.filter(function(element, i) {
    return element.id !== idToRemove;
});

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 eliminen los elementos) y elimina el elemento si se encuentra. Funciona en todos los navegadores.


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 de polyfill para asegurarse de que esto sea compatible con todos los navegadores.


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 nítidas.

Esta idea aquí resolverá su problema y también elimina todas las apariciones del argumento en lugar de solo 1 (o un valor específico).

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]

OK, por ejemplo, tiene la siguiente matriz:

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

Y queremos eliminar el número 4, simplemente puede hacer el siguiente código:

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

Si reutiliza esta función, escribe una función reutilizable que se adjuntará a la función de matriz nativa como 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 lugar de unos pocos [5] s en la matriz?

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

Necesitamos un bucle para verificarlos a todos, pero de manera más fácil y eficiente es usar las funciones incorporadas de JavaScript, 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, consulte lodash _.pull, _.pullAt o _.without.


Sobre la base de todas las respuestas que fueron principalmente correctas y teniendo en cuenta las mejores prácticas sugeridas (especialmente no utilizando Array.prototype directamente), se me ocurrió el siguiente código:

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

Al revisar la función anterior, a pesar de que funciona bien, me di cuenta de que podría haber alguna mejora en el rendimiento. También usar ES6 en lugar de ES5 es un enfoque mucho mejor. Para ello, este es el código mejorado:

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

Cómo utilizar:

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)

Actualmente estoy escribiendo una publicación de blog en la que he evaluado varias soluciones para Array sin problemas y comparé el tiempo que lleva correr. Actualizaré esta respuesta con el enlace una vez que termine esa publicación. Solo para hacerle saber, comparé lo anterior con el de lodash y, en caso de que el navegador lo soporte Map, ¡supera al de lodash! ¡Tenga en cuenta que no estoy usando Array.prototype.indexOfo Array.prototype.includesenvolviendo exlcudeValues ​​en una Mapo Objecthace que la consulta sea más rápida! ( https://jsperf.com/array-without-benchmark-against-lodash )


Tengo otra buena solución para eliminar de una matriz:

var words = ['spray', 'limit', 'elite', 'exuberant', 'destruction', 'present'];

const result = words.filter(word => word.length > 6);

console.log(result);
// expected output: Array ["exuberant", "destruction", "present"]

filter


Sé que ya hay muchas respuestas, pero muchas de ellas parecen complicar el problema en exceso. Esta es una forma 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 los navegadores indexOf, pero es simple y puede rellenarse 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);
}

Metodo prototipo

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

    if(index === -1) return;

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

  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