2015-05-07 2 views
12

Non vedo un modo per gli oggetti find quando la mia condizione implicherebbe un array nidificato.Trova oggetto per proprietà di corrispondenza nell'array nidificato

var modules = [{ 
    name: 'Module1', 
    submodules: [{ 
     name: 'Submodule1', 
     id: 1 
     }, { 
     name: 'Submodule2', 
     id: 2 
     } 
    ] 
    }, { 
    name: 'Module2', 
    submodules: [{ 
     name: 'Submodule1', 
     id: 3 
     }, { 
     name: 'Submodule2', 
     id: 4 
     } 
    ] 
    } 
]; 

Questo non funzionerà perché submodules è un array, non un oggetto. C'è qualche stenografia che farebbe funzionare questo? Sto cercando di evitare di ripetere manualmente l'array.

_.where(modules, {submodules:{id:3}}); 

risposta

10

Ecco cosa mi è venuta:

_.find(modules, _.flow(
    _.property('submodules'), 
    _.partialRight(_.some, { id: 2 }) 
)); 
// → { name: 'Module1', ... } 

Utilizzando flow(), è possibile costruire una funzione di callback che fa quello che vi serve. Quando si chiama, i dati flussi attraverso ciascuna funzione. La prima cosa che vuoi è la proprietà submodules, e puoi ottenerla usando la funzione property().

L'array di sottomoduli viene quindi inserito in some(), che restituisce true se contiene il sottomodulo che si sta cercando, in questo caso, ID 2.

Sostituisci find() con filter() se stai cercando più moduli e non solo il primo trovato.

+0

Mi piace, grazie! Non proprio elegante come potrebbe esserlo un percorso dinamico, ma lodash non lo supporta. Forse farò un mixin ... – helion3

+2

A proposito, in Lodash 4.0, hanno rimosso la funzione .any(). Ora useresti .some(). – Justin

0

Penso che la tua migliore possibilità stia usando una funzione, per ottenere il modulo.

_.select(modules, function (module) { 
    return _.any(module.submodules, function (submodule) { 
    return _.where(submodule, {id:3}); 
    }); 
}); 

provare questo per ottenere il modulo

.dove ( .pluck (moduli, "moduli"), {sottomoduli: {id: 3}});

+0

Buona idea. Devo usare '_flatten' in aggiunta perché' _.pluck' restituisce una matrice di matrici. – helion3

+0

(sì mi sono appiattito in seguito), ma ho cambiato completamente la mia risposta, perché non avrebbe funzionato. speranzoso pensiero :) – Mabedan

+1

Ma ha funzionato. Usando la logica flatten + pluck, il mio test funziona. http://jsbin.com/howazulexe/1/edit?js – helion3

22

Lodash consente di filtrare i dati in annidati (compresi gli array) come questo:

_.filter(modules, { submodules: [ { id: 2 } ]});

+2

È possibile utilizzare la stessa sintassi esatta con '_.find'. –

+1

Questa dovrebbe essere la risposta accettata – blak3r

+1

@DevonSams anche se '_.filter' restituisce l'array filtrato o un array vuoto e' _.find' restituisce l'elemento corrispondente che potrebbe essere un oggetto, array, numero, stringa, booleano o non definito. – mjwatts