vacios remover objetos objeto item especifico eliminar elementos elemento como asociativo arreglo array javascript immutable.js

remover - eliminar un elemento especifico de un array javascript



¿Cómo eliminar un objeto de una matriz en Immutable? (6)

Dado un estado como este:

state = { things: [ { id: ''a1'', name: ''thing 1'' }, { id: ''a2'', name: ''thing 2'' }, ], };

¿Cómo puedo crear un nuevo estado donde se elimina la ID "a1"? Es bastante fácil empujar nuevos elementos:

return state.set(state.get(''things'').push(newThing));

Pero no puedo averiguar cómo buscar y eliminar un objeto por su propiedad id . Intenté esto:

return state.set(''tracks'', state.get(''tracks'').delete( state.get(''tracks'').findIndex(x => x.get(''id'') === ''a2'') ) )

Pero parece desordenado, y solo funciona si se encuentra el elemento, porque si findIndex devuelve -1 , ese es un valor válido para delete .


ImmutableJS trabajando con matrices anidadas

Immutablejs es excelente, pero al mismo tiempo complica las cosas en algunos casos, especialmente cuando se trabaja con matrices anidadas .

A veces es más fácil devolverlo a JS en un sentido general para este problema en particular.

// 1. get a copy of the list into normal JavaScript const myList = state.getIn([''root'', ''someMap'', ''myList'']).toJS() // 2. remove item in list using normal JavaScript and/or anything else myList.splice(deleteIndex, 1) // 3. return the new state based on mutated myList return state .mergeDeep({ root: { someMap: { myList: undefined } }}) .mergeDeep({ root: { someMap: { myList } }})

Desafortunadamente, el paso 3 es necesario para configurarlo específicamente como undefined porque si simplemente configura myList directamente como un valor de matriz, ImmutableJS hará una comparación de valores entre la lista actual y solo los modificará creando un comportamiento extraño.

La justificación para esto es simplificar la sobrecarga mental. No recomiendo hacer esto en un bucle, sino manipular la matriz JS pura en un bucle si debe hacerlo antes del paso 3.


Alternativamente, cuando esté "buscando y luego borrando" ...

var itemIndex = this.state.get("tracks").findIndex(x => x.get(''id'') === ''a2''); return itemIndex > -1 ? this.state.deleteIn(["tracks", itemIndex]) : this.state;

Esto asegurará que el estado no se mute cuando no hay cambios.


Cuando está usando el filtro, itera todo el ciclo -> una forma efectiva es encontrar index => slice y usar splitter ...

const index = state.findIndex(data => data.id === action.id); return [...state.slice(0, index), ...state.slice(index + 1)];


Encontré este hilo mientras buscaba una solución para una tarea similar. Resuelto con el método de update :

return state.update(''things'', (things) => things.filter((t) => t.id !== action.things.id))

¿Alguna idea / comentario cuál es mejor / preferido?


Puede utilizar Array#filter .

return state.set(''things'', state.get(''things'').filter(o => o.get(''id'') !== ''a1''));


Puedes hacerlo incluso sin immutable.js con la siguiente función.

function arrayFilter(array, filter) { let ret = array let removed = 0 for (let index = 0; index < array.length; index++) { const passed = filter(array[index], index, array) if (!passed) { ret = [...ret.slice(0, index - removed), ...ret.slice(index - removed + 1)] removed++ } } return ret }