2016-02-11 13 views
13

C'è un modo elegante per rimuovere un oggetto da un array che fa parte di un array? Ho lavorato con React e Redux per un po 'di tempo ma mi sono bloccato diverse ore ogni volta che devo rimuovere o inserire dati senza mutare lo stato.Rimuovere i dati dagli oggetti nidificati senza mutare

Il riduttore è un array contenente oggetti che hanno un ID e un altro array con gli oggetti, in questo modo:

[ 
{ id:123, 
    items:[ 
      { id: abc, 
      name: albert 
      }, 
      ... 
     ] 
}, 
... 
] 

ricevo entrambi gli ID e la necessità di rimuovere l'elemento con ID abc.

+1

Si consiglia di leggere questo e riconsiderare la vostra struttura statale. http://stackoverflow.com/questions/32135779/updating-nested-data-in-redux-store/32921731#32921731 – larrydahooster

+0

Invece di passare l'intero array complesso al riduttore, creare un nuovo riduttore che riceve l'elemento dell'array come lo stato di fare il cambiamento –

+0

Bene, questo è anche un modo per farlo. Ma ogni volta che ho bisogno degli oggetti dell'oggetto con id: 123, devo "cercare" dem. E un'altra domanda, quando ricevo il JSON come questo dal backend, come lo divido a diversi riduttori? Il recupero avviene tramite un'azione che va a un riduttore. –

risposta

28

Per rimuovere un elemento da un array da ID:

return state.filter(item => item.id !== action.id) 

per rimuovere una chiave da un oggetto da id:

let copy = Object.assign({}, state) // assuming you use Object.assign() polyfill! 
delete copy[action.id] // shallowly mutating a shallow copy is fine 
return copy 

(bonus) Lo stesso con object spread operator proposal:

let { [action.id]: deletedItem, ...rest } = state 
return rest 
+0

Una combinazione di questi è quello che ho finito per usare. –

+0

Cosa fa 'deletedItem' do/mean/contiene nell'ultimo esempio? – Mbrevda

+0

@Mbrevda 'deletedItem' è solo un nome di variabile a cui è stato assegnato l'elemento che è stato eliminato (l'elemento assegnato a' action.id'). Stai trasformando il tuo stato in due nuovi oggetti, uno con l'oggetto rifiutato, l'altro con gli altri elementi. –

0

È possibile utilizzare Underscore's reject. Fa esattamente quello che stai cercando di fare.

+0

Restituisce array non oggetto. – Sassan

0

Se si decide per la pianura Javascript, il modo più elegante che posso pensare è quello di utilizzare Array.prototype.reduce per ridurre lo stato:

var state = [ 
{ id: 123, 
    items:[ 
      { id: 'abc', 
      name: 'albert' 
      }, 
      ... 
     ] 
}, 
... 
] 

function filterOut (state) { 
    return (bucketId, personId) => { 
    return state.reduce((state, bucket) => { 
     return state.concat(
     (bucketId === bucket.id) ? 
      Object.assign({}, bucket, {items: bucket.items.filter((person) => person.id !== personId)}) : 
      bucket 
    ); 
    }, []); 
    } 
} 

var newState = filterOut(state)(123, 'abc'); 
0

È anche possibile utilizzare lodash's omit method.

Si noti che l'importazione di lodash aumenterà un po 'le dimensioni della build. Tenere sotto controllo un po 'importando solo il metodo specifico: import omit from 'lodash/omit';

Se possibile, io suggerisco di usare l'oggetto operatore di diffusione, come descritto nella Dan's answer.

0

ho risolto il mio problema in questo modo

if(action.type === "REMOVE_FROM_PLAYLIST"){ 
     let copy = Object.assign({}, state) 
     delete copy.playlist[action.index].songs[action.indexSongs]; 

     return copy; 
    } 

Speranza che aiuta chiunque altro.

2
const remove = (state, bucketId, personId) => state.map(
    bucket => bucket.id === bucketId 
    ? { ...bucket, items: bucket.items.filter(person => person.id !== personId) } 
    : bucket, 
); 

Usage:

const state = [ 
    { 
    id: 123, 
    items: [ 
     { 
     id: 'abc', 
     name: 'Kinna', 
     }, 
     { 
     id: 'def', 
     name: 'Meggy', 
     }, 
    ], 
    }, 
    { 
    id: 456, 
    items: [ 
     { 
     id: 'ghi', 
     name: 'Ade', 
     }, 
     { 
     id: 'jkl', 
     name: 'Tades', 
     }, 
    ], 
    }, 
]; 

console.log(remove(state, 123, 'abc')); 
Problemi correlati