2013-10-21 4 views
29

Sto cercando di cercare attraverso una serie di oggetti usando Underscore.js, ma non riesco a scegliere quello che voglio.Ottieni un oggetto dall'array che contiene un valore specifico

console.log(_.findWhere(response.data, { TaskCategory: { TaskCategoryId: $routeParams.TaskCategory } })); 

Tuttavia, questo sta tornando undefined $routeParams.TaskCategory è uguale 301

Questo è un esempio di oggetti all'interno della matrice Cerco. Questi dati è rappresentata da data.response

[{ 
    "TaskCategory": { 
     "TaskCategoryId": 201, 
     "TaskName": "TaskName" 
    }, 
    "TaskCount": 1, 
    "Tasks": [{ 
     "EventTypeId": 201, 
     "EventName": "Event Driver", 
     "EventDate": "0001-01-01T00:00:00", 
     "EventId": "00000000-0000-0000-0000-000000000000", 
    }] 
}, 
{ 
    "TaskCategory": { 
     "TaskCategoryId": 301, 
     "TaskName": "TaskName" 
    }, 
    "TaskCount": 1, 
    "Tasks": [{ 
     "EventTypeId": 201, 
     "EventName": "Event Driver", 
     "EventDate": "0001-01-01T00:00:00", 
     "EventId": "00000000-0000-0000-0000-000000000000", 
    }] 
}] 

Quindi voglio il secondo oggetto di tale array utilizzando il TaskCategory.TaskCategoryId, è possibile ottenere utilizzando sottolineatura?

risposta

49

Uso _.find invece di findWhere:

console.log(_.find(response.data, function(item) { 
    return item.TaskCategory.TaskCategoryId == $routeParams.TaskCategory; 
})); 

Sono simili, ma findWhere è progettato per i casi particolari in cui si desidera abbinare coppie chiave-valore (non utili per lo scenario in quanto coinvolge gli oggetti nidificati). Find è più generale, perché consente di fornire una funzione come predicato.

+0

inserimento del filtro sarebbe un sostituto per l'utilizzo '_.where' in questo caso. Dovrebbe usare '_.find' piuttosto che' _.filter'. – forivall

+0

@forivall oh, ovviamente ... grazie. Il filtro cercherebbe l'intera raccolta, mentre la ricerca si ferma alla prima partita. Ho aggiornato. – McGarnagle

+0

Grazie ragazzi, il '_.find' ha funzionato perfettamente. Ho davvero bisogno di sedermi con questa libreria e impararla per un weekend. – Neil

6

La fonte di _.findWhere/_.where è la seguente

_.where = function(obj, attrs, first) { 
    if (_.isEmpty(attrs)) return first ? void 0 : []; 
    return _[first ? 'find' : 'filter'](obj, function(value) { 
    for (var key in attrs) { 
     if (attrs[key] !== value[key]) return false; 
    } 
    return true; 
    }); 
}; 

_.findWhere = function(obj, attrs) { 
    return _.where(obj, attrs, true); 
}; 

Come si può vedere, si svolge una rigorosa parità piuttosto che l'uguaglianza profonda. Se si desidera una ricerca profonda in cui, ciò sarebbe sufficiente (non testato, non ottimizzata):

_.whereDeep = function(obj, attrs, first) { 
    if (_.isEmpty(attrs)) return first ? void 0 : []; 
    return _[first ? 'find' : 'filter'](obj, function(value) { 
    for (var key in attrs) { 
     if (attrs[key] !== value[key] || !(_.isObject(attrs[key]) && _.whereDeep([value[key]], attrs[key], true))) return false; 
    } 
    return true; 
    }); 
}; 

_.findWhereDeep = function(obj, attrs) { 
    return _.whereDeep(obj, attrs, true); 
}; 

E si sarebbe in grado di utilizzare il codice, quasi invariato

_.findWhereDeep(response.data, { TaskCategory: { TaskCategoryId: $routeParams.TaskCategory } });