2013-10-21 117 views
29

我正在嘗試使用Underscore.js搜索對象數組,但似乎無法定位到我想要的目標。從包含特定值的數組中獲取對象

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

然而,這是回訪undefined $routeParams.TaskCategory等於301

這是陣列我尋找內部的對象的一個​​例子。此數據由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", 
    }] 
}] 

所以代表我想用TaskCategory.TaskCategoryId數組中的第二個對象,是有可能用它來下劃線得到?而不是findWhere

回答

49

使用_.find

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

它們是相似的,但findWhere是專爲要匹配的鍵值對(在您的情況沒有什麼用處,因爲它涉及到嵌套對象)的特殊情況。 Find更通用,因爲它可以讓你提供一個函數作爲謂詞。

+0

使用過濾器將使用替代在這種情況下'_.where'。他應該使用'_.find'而不是'_.filter'。 – forivall

+0

@forivall哦,當然......謝謝。過濾器將搜索整個集合,而在第一場比賽中找到停止位置。我已更新。 – McGarnagle

+0

謝謝你們,'_.find'完美無缺。我真的需要坐下來和這個圖書館一起週末學習。 – Neil

6

_.findWhere/_.where來源是如下

_.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); 
}; 

正如你所看到的,它會執行嚴格的平等,而不是深平等。如果你想有一個深刻的搜索過程中,這就夠了(未經檢驗,未優化):

_.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); 
}; 

你將能夠使用你的代碼,幾乎沒有變化

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