¿Cómo puedo eliminar un elemento de una lista, con lodash?

165

Tengo un objeto que se ve así:

var obj = {
    "objectiveDetailId": 285,
    "objectiveId": 29,
    "number": 1,
    "text": "x",
    "subTopics": [{
        "subTopicId": 1,
        "number": 1
    }, {
        "subTopicId": 2,
        "number": 32
    }, {
        "subTopicId": 3,
        "number": 22
    }]
}
var stToDelete = 2;

He lodashinstalado en mi aplicación para otras cosas. ¿Hay una manera eficiente de usar lodashpara eliminar la entrada: {"subTopicId":2, "number":32}del objobjeto?

¿O hay una forma de JavaScript para hacer esto?

Samantha JT Star
fuente
1
simplemente puede usar splice( developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/… ) para eliminar el elemento de una lista
z33m
1
Cambió el título porque no se puede eliminar 4 de una matriz [1,4,5] de esta manera. Sí, entiendo que las matrices se pueden implementar desde el hash / objeto y probablemente lo sean, pero hay una sutil diferencia en estos dos. Para eliminar de una matriz, usaría result = _.pull(arr, value) Esto eliminaría todos los valores coincidentes de la lista.
Boatcoder

Respuestas:

247

Como Lyyons señaló en los comentarios, una forma más idiomática y descarada de hacer esto sería usar _.remove, así

_.remove(obj.subTopics, {
    subTopicId: stToDelete
});

Además de eso, puede pasar una función de predicado cuyo resultado se utilizará para determinar si el elemento actual debe eliminarse o no.

_.remove(obj.subTopics, function(currentObject) {
    return currentObject.subTopicId === stToDelete;
});

Alternativamente, puede crear una nueva matriz filtrando la anterior _.filtery asignarla al mismo objeto, de esta manera

obj.subTopics = _.filter(obj.subTopics, function(currentObject) {
    return currentObject.subTopicId !== stToDelete;
});

O

obj.subTopics = _.filter(obj.subTopics, {subTopicId: stToKeep});
thefourtheye
fuente
3
La razón por la que esta respuesta es genial es porque puedes usar una función de predicado , que es exactamente lo que estaba buscando. Eliminar un elemento es trivial si conoce el índice, pero ¿qué pasa cuando no conoce el índice?
random_user_name
3
Vale la pena mencionar _.filter si no quieres mutar la matriz original ...
random_user_name
@cale_b Gracias :-) Actualizó la respuesta con la _.filterversión.
thefourtheye
77
@thefourtheye _.filter devuelve un elemento si el predicado es verdadero. Su implementación devolverá todos los elementos no deseados en lugar de aquellos que desea conservar
Xeltor
55
@thefourtheye debe usar en _.rejectlugar de _.filterusar el mismo predicado. ¡Mira mi respuesta para más detalles!
Xeltor
29

Solo usa vanilla JS. Puede usar splicepara eliminar el elemento:

obj.subTopics.splice(1, 1);

Manifestación

Andy
fuente
3
el usuario preguntaIs there an efficient way to use _lodash to delete
semirturgay
77
@Andy Tienes razón, pero ¿qué pasa si el índice aún no se conoce?
thefourtheye
3
splice () es el mejor enfoque si desea que su matriz sea mutada. Si usa remove, devuelve la nueva matriz y debe reasignarse.
omarjebari
Si desea eliminar un elemento de una matriz por su índice en la matriz (obviamente, tiene este índice si desea realizar la acción de eliminar de esta manera), entonces usar el método de empalme es la forma más eficiente (y fácil) para hacerlo. No es necesario comparar nada y hacer que el código sea más complicado y vulnerable a errores y errores ...
TheCuBeMan
26

puedes hacerlo con _pull.

_.pull(obj["subTopics"] , {"subTopicId":2, "number":32});

verifique la referencia

semirturgay
fuente
77
Según los documentos, _.pullutiliza la igualdad estricta para las comparaciones, es decir, === . Dos objetos planos diferentes nunca se compararán como iguales por ===(o por ==si acaso). Por lo tanto, su código anterior nunca eliminará ningún elemento de la matriz.
Mark Amery
1
Sin embargo, ese es el único que funciona con cadenas en matriz. _.removesimplemente enjuaga la matriz.
Yauheni Prakopchyk
3
Sigo pensando que esta es la respuesta correcta. JS .filter elimina todos los elementos que coinciden, JS .splice requiere que conozca el índice, _.remove itera sobre todos los elementos de la matriz, por lo que es menos eficiente. _.pull es exactamente lo que quiero: _.pull (array, itemToRemove).
Judá Gabriel Himango
21

Ahora puede usar _.reject que le permite filtrar en función de lo que necesita deshacerse, en lugar de lo que necesita conservar.

a diferencia _.pullo _.removeque solo funciona en matrices, ._rejectestá trabajando en cualquier Collection

obj.subTopics = _.reject(obj.subTopics, (o) => {
  return o.number >= 32;
});
Xeltor
fuente
2

Hay cuatro formas de hacer esto, como sé

const array = [{id:1,name:'Jim'},{id:2,name:'Parker'}];
const toDelete = 1;

El primero:

_.reject(array, {id:toDelete})

El segundo es:

_.remove(array, {id:toDelete})

De esta manera, la matriz será mutada.

El tercero es:

_.differenceBy(array,[{id:toDelete}],'id')
// If you can get remove item 
// _.differenceWith(array,[removeItem])

El último es:

_.filter(array,({id})=>id!==toDelete)

Estoy aprendiendo lodash

Responda para hacer un registro, para que pueda encontrarlo más tarde.

mqliutie
fuente
Estaba buscandoreject
Sampgun
2

Además de la respuesta @thefourtheye, usando predicado en lugar de funciones anónimas tradicionales:

  _.remove(obj.subTopics, (currentObject) => {
        return currentObject.subTopicId === stToDelete;
    });

O

obj.subTopics = _.filter(obj.subTopics, (currentObject) => {
    return currentObject.subTopicId !== stToDelete;
});
Pranav Singh
fuente
1

lodash y mecanografiado

const clearSubTopics = _.filter(obj.subTopics, topic => (!_.isEqual(topic.subTopicId, 2)));
console.log(clearSubTopics);
Uliana Pavelko
fuente
0

Aquí está la función lodash simple con matriz y eliminarla con el número de índice.

index_tobe_delete = 1

fruit = [{a: "apple"}, {b: "banana"}, {c: "choco"}]
_.filter(fruit, (value, key)=> {
return (key !== index_tobe_delete)
})
Anupam Maurya
fuente