Eliminar elemento de matriz en función de la propiedad del objeto


271

Tengo una variedad de objetos así:

var myArray = [
    {field: 'id', operator: 'eq', value: id}, 
    {field: 'cStatus', operator: 'eq', value: cStatus}, 
    {field: 'money', operator: 'eq', value: money}
];

¿Cómo elimino uno específico en función de su propiedad?

Por ejemplo, ¿cómo eliminaría el objeto de matriz con 'dinero' como propiedad del campo?

Respuestas:


384

Una posibilidad:

myArray = myArray.filter(function( obj ) {
    return obj.field !== 'money';
});

Tenga en cuenta que filtercrea una nueva matriz. Cualquier otra variable que se refiera a la matriz original no obtendrá los datos filtrados aunque actualice su variable original myArraycon la nueva referencia. Usar con precaución.


66
Tenga en cuenta que filter()solo está disponible para Internet Explorer 9+
jessegavin

@jessegavin de hecho. Debería haber mencionado que hay un montón de buena ES5 cuña bibliotecas disponibles, que imitan la funcionalidad (en caso de que quieren navegadores ayuda de la herencia)
Jandy

3
filter()crea una nueva matriz, lo cual está bien si puede reasignar la variable y saber que no hay otras áreas de código que tengan referencias a ella. Esto no funcionará si necesita modificar específicamente el objeto de matriz original.
Brian Glick

2
¿Qué sucede si la matriz es una estructura de árbol ar beforeDeleteOperationArray = [{"id": 3.1, "name": "test 3.1", "activityDetails": [{"id": 22, "name": "test 3.1"}, {"id": 23, "name": "cambió la prueba 23"}]}] y quiero eliminar id: 23
forgottofly

@forgottofly buen punto: la respuesta funciona solo para casos limitados. ¿Encontró respuesta a su pregunta?
JackTheKnife

88

Itere a través de la matriz y spliceelimine los que no desea. Para un uso más fácil, itere hacia atrás para que no tenga que tener en cuenta la naturaleza viva de la matriz:

for (var i = myArray.length - 1; i >= 0; --i) {
    if (myArray[i].field == "money") {
        myArray.splice(i,1);
    }
}

3
¿Qué quieres decir con la naturaleza viva de la matriz? @Neit the Dark Absol
sisimh

29
@sisimh quiere decir que si itera hacia adelante sobre una matriz usando su longitud como parte de la lógica de iteración y su longitud cambia porque tiene elementos eliminados o agregados, puede terminar corriendo fuera del final de la matriz o no realizar la operación para cada artículo en la matriz. Retroceder hace que sea mucho menos probable, ya que funciona hacia un índice 0 estático en lugar de una longitud móvil.
Klors

2
¿Qué sucede si la matriz es una estructura de árbol ar beforeDeleteOperationArray = [{"id": 3.1, "name": "test 3.1", "activityDetails": [{"id": 22, "name": "test 3.1"}, {"id": 23, "name": "cambió la prueba 23"}]}] y quiero eliminar id: 23
forgottofly

Es obvio, pero si solo espera eliminar un elemento único, puede interrumpir la declaración 'if' de rendimiento para que el ciclo no repita innecesariamente sobre el resto de la matriz.
Patrick Borkowicz

@Klors Gracias por explicar. ¿Es bueno leer siempre la matriz al revés como en la respuesta?
kittu

38

Supongamos que desea eliminar el segundo objeto por su propiedad de campo.

Con ES6 es tan fácil como esto.

myArray.splice(myArray.findIndex(item => item.field === "cStatus"), 1)

77
Intenté esto, pero en lugar de "eliminar" el tercer elemento de la matriz de OP, su código se "filtró" y mostró solo el tercer elemento.
Compaq LE2202x

1
@ CompaqLE2202x 2 años después, probablemente ya sea obvio para usted, pero para futuros desarrolladores: splicecambia la matriz original, por lo que el valor que recupera es el elemento que se eliminó, pero si echa un vistazo al myArrayelemento que falta.
David Mulder

17

Puede usar findIndex de lodash para obtener el índice del elemento específico y luego empalmarlo.

myArray.splice(_.findIndex(myArray, function(item) {
    return item.value === 'money';
}), 1);

Actualizar

También puede usar findIndex () de ES6

El método findIndex () devuelve el índice del primer elemento de la matriz que satisface la función de prueba proporcionada. De lo contrario, se devuelve -1.

myArray.splice(myArray.findIndex(myArray, function(item) {
    return item.value === 'money';
}), 1);

¿Cuál es la matriz es una estructura de árbol?
forgottofly

@forgottofly estructura de árbol? Creo que myArrayaquí hay una gran variedad de objetos.
Sridhar

44
¿Qué sucede si la matriz es una estructura de árbol var beforeDeleteOperationArray = [{"id": 3.1, "name": "test 3.1", "activityDetails": [{"id": 22, "name": "test 3.1"}, {"id": 23, "name": "cambió la prueba 23"}]}] y quiero eliminar id: 23
forgottofly

9

Aquí hay otra opción usando jQuery grep. Pase truecomo el tercer parámetro para garantizar que grep elimine los elementos que coincidan con su función.

users = $.grep(users, function(el, idx) {return el.field == "money"}, true)

Si ya está usando jQuery, entonces no se requiere una cuña, lo que podría ser útil en lugar de usar Array.filter.


8

En ES6, solo una línea.

const arr = arr.filter(item => item.key !== "some value");

:)


3

El siguiente es el código si no está utilizando jQuery. Manifestación

var myArray = [
    {field: 'id', operator: 'eq', value: 'id'}, 
    {field: 'cStatus', operator: 'eq', value: 'cStatus'}, 
    {field: 'money', operator: 'eq', value: 'money'}
];

alert(myArray.length);

for(var i=0 ; i<myArray.length; i++)
{
    if(myArray[i].value=='money')
        myArray.splice(i);
}

alert(myArray.length);

También puede usar la biblioteca de subrayado que tiene muchas funciones.

Underscore es una biblioteca de cinturón de utilidades para JavaScript que proporciona una gran cantidad de soporte de programación funcional


55
Este es un ejemplo muy peligroso para dejar en la web ... funciona con los datos de ejemplo, pero no con cualquier otra cosa. splice (i) significa que eliminará todos los elementos de la matriz comenzando en y después de la primera instancia donde el valor es dinero, lo que no satisface el requisito de op en absoluto. Si cambiamos a empalme (i, 1) aún sería incorrecto porque no evaluaría el siguiente elemento secuencial (también tendría que disminuir i). Es por eso que debe procesar las operaciones de eliminación en matrices hacia atrás, de modo que eliminar un el elemento no altera los índices de los siguientes elementos a procesar
Chris Schaller

3
var myArray = [
    {field: 'id', operator: 'eq', value: id}, 
    {field: 'cStatus', operator: 'eq', value: cStatus}, 
    {field: 'money', operator: 'eq', value: money}
];
console.log(myArray.length); //3
myArray = $.grep(myArray, function(element, index){return element.field == "money"}, true);
console.log(myArray.length); //2

El elemento es un objeto en la matriz. El tercer parámetro truesignifica que devolverá una matriz de elementos que falla la lógica de su función, los falsemedios devolverán una matriz de elementos que falla la lógica de su función.


3

En base a algunos comentarios anteriores, a continuación se encuentra el código de cómo eliminar un objeto en función de un nombre y un valor clave

 var items = [ 
  { "id": 3.1, "name": "test 3.1"}, 
  { "id": 22, "name": "test 3.1" }, 
  { "id": 23, "name": "changed test 23" } 
  ]

    function removeByKey(array, params){
      array.some(function(item, index) {
        return (array[index][params.key] === params.value) ? !!(array.splice(index, 1)) : false;
      });
      return array;
    }

    var removed = removeByKey(items, {
      key: 'id',
      value: 23
    });

    console.log(removed);

3

Usando la biblioteca lodash :

var myArray = [
    {field: 'id', operator: 'eq', value: 'id'}, 
    {field: 'cStatus', operator: 'eq', value: 'cStatus'}, 
    {field: 'money', operator: 'eq', value: 'money'}
];
var newArray = _.remove(myArray, function(n) {
  return n.value === 'money';;
});
console.log('Array');
console.log(myArray);
console.log('New Array');
console.log(newArray);
<script src="https://cdnjs.cloudflare.com/ajax/libs/lodash.js/4.17.5/lodash.js"></script>


1

La solución de jAndy es probablemente la mejor, pero si no puede confiar en el filtro, puede hacer algo como:

var myArray = [
    {field: 'id', operator: 'eq', value: 'id'}, 
    {field: 'cStatus', operator: 'eq', value: 'cStatus'}, 
    {field: 'money', operator: 'eq', value: "money"}
];

myArray.remove_key = function(key){
    var i = 0, 
        keyval = null;
    for( ; i < this.length; i++){
        if(this[i].field == key){
            keyval = this.splice(i, 1);
            break;
        }
    }
    return keyval;
}

1
¿Por qué no podría confiar en filter ()?
imperium2335

2
Porque es parte de JavaScript 1.6, que no es compatible con IE8 y navegadores anteriores o anteriores.
Rob M.

-1

Usar la biblioteca lodash es tan simple como esto

_.remove(myArray , { field: 'money' });
Al usar nuestro sitio, usted reconoce que ha leído y comprende nuestra Política de Cookies y Política de Privacidad.
Licensed under cc by-sa 3.0 with attribution required.