2014-02-06 17 views
21

Wie gehe ich über die Filterung unter:Underscore.js: Findwhere mit verschachteltem Eigenschaftswert

[{ 
    "id": 100, 
    "title": "Tlt1", 
    "tax": [{ 
     "name": "Tax1", 
     "id": 15 
    }, { 
     "name": "Tax1", 
     "id": 17 
    }] 
}, { 
    "id": 101, 
    "title": "Tlt2", 
    "tax": [{ 
     "name": "Tax2", 
     "id": 16 
    }] 
}, { 
    "id": 102, 
    "title": "Tlt3", 
    "tax": [{ 
     "name": "Tax3", 
     "id": 17 
    }, { 
     "name": "Tax3", 
     "id": 18 
    }] 
}] 

zu erhalten nur diejenigen, bei denen tax.id17 sind, wie weiter unten auf:

[ 
    { 
     "id": 100, 
     "title": "Tlt1", 
     "tax": [ 
      { 
       "name": "Tax1", 
       "id": 15 
      }, 
      { 
       "name": "Tax1", 
       "id": 17 
      } 
     ] 
    }, 
    { 
     "id": 102, 
     "title": "Tlt3", 
     "tax": [ 
      { 
       "name": "Tax3", 
       "id": 17 
      }, 
      { 
       "name": "Tax3", 
       "id": 18 
      } 
     ] 
    } 
] 

Derzeit I Verwenden Sie die Methode unten, aber vielleicht gibt es mehr saubere Art und Weise, dies zu tun?

var arr = []; 
_(data).each(function (v1, k1) { 
    _(v1.tax).each(function (v2, k2) { 
     if (v2.id == id) { 
      arr.push(v1); 
     } 
    }); 
}); 

Demo hier: http://jsfiddle.net/7gcCz/2/

Jeder Vorschlag sehr geschätzt.

+0

Dies ist ein Kandidat für die CR sein könnte ... –

Antwort

42

Sie können die Kombination von _.filter verwenden und _.where

_.filter(data, function(obj) { 
    return _.where(obj.tax, {id: ID_TO_FIND}).length > 0; 
}) 

Siehe Demo: http://jsfiddle.net/hCVxp/

aktualisieren


Dank @GruffBunny. Eine effizientere Art und Weise ist _.some zu verwenden, um durch alle tax Artikel zu vermeiden Looping:

var arr = _.filter(data, function(obj) { 
    return _.some(obj.tax, {id: ID_TO_FIND}); 
}); 

Siehe Demo: http://jsbin.com/putefarade/1/edit?html,js,console

+5

Faust Zeit mit 'underscore', Erster Roadbump, Erste-Link auf der Google, FTW! – MattSizzle

+1

Auch wenn Steuern nur ein Objekt ist, muss man es auf ein Array setzen, um dieses Ding zu bearbeiten. So etwas wie _some ([obj.tax], {id: ID_TO_FIND}); –

17

Verwenden _.filter die Kandidatenpositionen und _.some zu überprüfen, für die Existenz eines finden Artikel in einer Sammlung:

var filteredList = _.filter(list, function(item){ 
    return _.some(item.tax, { id: 17 }); 
}); 
+0

Ich denke, dass diese Antwort leistungsfähiger ist als die oben angenommene Antwort. –

+0

kann ich _.findWhere innerhalb des Filters verwenden? – Jain

3

Sie können dies mit _.where alone tun.

var filteredList = _.where(list, { tax:[{id:17}] }); 

Edit: Diese Methode funktioniert in älteren Version von Lodash, aber wird nicht in aktuellen Unterstrich oder Lodash arbeiten. Arbeitsbeispiel sowieso: https://jsfiddle.net/rhp4crma/

+0

Kann mir jemand sagen, warum dies abgelehnt wird? Ich habe es getestet und es liefert das genaue Ergebnis, das OP mit nur einem Befehl angefordert hat. – Gray

+0

Ich habe das versucht und es funktioniert nicht. Mine gibt undefined zurück, obwohl das Objekt vorhanden ist – tno2007

+1

korrekte Syntax lautet: var filteredList = _.where (list, {tax: {id: 17}}); – Sam