2013-02-27 13 views
20

Sto provando a filtrare una matrice di oggetti, sulla base di un'altra. L'ID proprietà comune id. Non sono sicuro filtro + ognuno è il modo migliore per farlo o ridurre la mappa. In ogni caso, sotto il codice non funziona come out è la lista vuota.underscore.js filtra una serie di oggetti, sulla base di un'altra

var aaa = [ 
    {name: "AAA", id: 845}, 
    {name: "BBB", id: 839}, 
    {name: "CCC", id: 854} 
]; 
var bbb = [ 
    {id: 839}, 
    {id: 854} 
]; 

var out = _.filter(aaa, function(val){ 
    return _.each(this, function(val2){ 
     return val['id'] === val2['id'] 
    }); 
}, bbb); 

risposta

37

Basta creare un "set" degli ID validi e l'uso che "set" per fare il filtraggio:

var aaa = [ 
    {name: "AAA", id: 845}, 
    {name: "BBB", id: 839}, 
    {name: "CCC", id: 854} 
]; 
var bbb = [ 
    {id: 839}, 
    {id: 854} 
]; 

var ids = {}; 
_.each(bbb, function (bb) { ids[bb.id] = true; }); 

var out = _.filter(aaa, function (val) { 
    return ids[val.id]; 
}, bbb); 

riempimento ids è veloce, è n * amortized O (1), cioè O (n). Stesse riserve per il filtraggio.

Se si utilizza each(…) nel ciclo interno, si avrà O (n²). Per set di dati più grandi questo diventerebbe molto lento. Anche l'annidamento aggiuntivo rende il codice più difficile da leggere/capire a prima vista.

Vedi che il codice snipped in azione: http://jsfiddle.net/SMtX5/

+1

thans per la spiegazione e il ragionamento dietro. – bsr

2

È possibile utilizzare _.some(list, [iterator], [context]).

Restituisce vero se uno qualsiasi dei valori nella lista passare il iteratore prova verità.

var out = _.filter(aaa, function(val){ 
    return _.some(this,function(val2){ 
     return val2['id'] === val['id']; 
    }); 
}, bbb); 

Ecco jsfiddle. http://jsfiddle.net/h98ej/

+0

In base alla risposta accettata, è molto più veloce questa routine rispetto a ciò che è stato accettato? –

15

è possibile utilizzare per filtrare _.find:

_.filter(aaa, function(a){ 
    return _.find(bbb, function(b){ 
     return b.id === a.id; 
    }); 
}); 
1
bbb = bbb.map(_ => _.id) && aaa.filter(_ => bbb.indexOf(_.id) > -1) 

Hai solo bisogno di funzioni per gli array JS pure a farlo supponendo che il caso d'uso.

Problemi correlati