2013-10-21 14 views
29

Tôi đang cố gắng tìm kiếm qua một mảng các đối tượng bằng cách sử dụng Underscore.js, nhưng tôi dường như không thể nhắm mục tiêu đến giá trị mà tôi muốn.Lấy một đối tượng từ mảng có chứa một giá trị cụ thể

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

Tuy nhiên, điều này đang trở lại undefined $routeParams.TaskCategory bằng 301

Đây là một ví dụ về các đối tượng bên trong mảng tôi đang tìm kiếm. Những thông tin này được đại diện bởi 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", 
    }] 
}] 

Vì vậy, tôi muốn đối tượng thứ hai trong mảng bằng cách sử dụng TaskCategory.TaskCategoryId, là nó có thể để có được nó bằng cách sử gạch?

Trả lời

49

Sử dụng _.find thay vì findWhere:

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

Họ là tương tự, nhưng findWhere được thiết kế cho trường hợp đặc biệt, nơi bạn muốn để phù hợp với cặp khóa-giá trị (không hữu ích trong trường hợp của bạn vì nó liên quan đến đối tượng lồng nhau). Find là sử dụng chung hơn, vì nó cho phép bạn cung cấp một hàm làm vị từ.

+0

Sử dụng bộ lọc sẽ là một sự thay thế cho việc sử dụng '_.where' trong trường hợp này. Anh ta nên sử dụng '_.find' thay vì' _.filter'. – forivall

+0

@forivall oh, tất nhiên ... cảm ơn. Bộ lọc sẽ tìm kiếm toàn bộ bộ sưu tập, trong khi tìm thấy dừng lại ở trận đấu đầu tiên. Tôi đã cập nhật. – McGarnagle

+0

Cảm ơn các bạn, '_.find' đã làm việc hoàn hảo. Tôi thực sự cần phải ngồi xuống với thư viện này và tìm hiểu nó trong một ngày cuối tuần. – Neil

6

Nguồn _.findWhere/_.where như sau

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

Như bạn thấy, nó thực hiện bình đẳng nghiêm ngặt chứ không phải là bình đẳng sâu. Nếu bạn muốn có một tìm kiếm sâu nơi, điều này sẽ là đủ (chưa được kiểm tra, được tối ưu hóa):

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

Và bạn sẽ có thể sử dụng mã của bạn, hầu như không thay đổi

_.findWhereDeep(response.data, { TaskCategory: { TaskCategoryId: $routeParams.TaskCategory } }); 
Các vấn đề liên quan