2013-10-21 14 views
29

Underscore.jsを使用してオブジェクトの配列を検索しようとしていますが、目的のものをターゲットにすることができません。特定の値を含む配列からオブジェクトを取得する

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

しかし、これはundefined $routeParams.TaskCategoryを返すされる。これは、私が探していアレイ内のオブジェクトの一例である301

に等しいです。このデータは、私がTaskCategory.TaskCategoryIdを使用して、その配列の2番目のオブジェクトをしたいので、

[{ 
    "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", 
    }] 
}] 

data.responseで表され、それはアンダースコアを使用して取得することは可能でしょうか?代わりにfindWhereの

答えて

49

使用_.find

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

彼らは似ていますが、findWhereは、あなたが(それがネストされたオブジェクトを含むので、あなたのシナリオでは有用ではない)のキーと値のペアを一致させたい特別な場合のために設計されています。 Findは、述語として関数を提供できるので、より一般的です。あなたが見ることができるように

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

を次のように

+0

ほぼ横ばい、あなたのコードを使用することができるだろうこの場合は '_.where 'となります。彼は '_.filter'ではなく' _.find'を使うべきです。 – forivall

+0

@forivallああ、もちろん...ありがとう。フィルタはコレクション全体を検索しますが、findは最初の一致で停止します。私は更新しました。 – McGarnagle

+0

ありがとう、 '_.find'は完璧に機能しました。私は本当にこの図書館に座って週末にそれを学ぶ必要があります。 – Neil

6

_.findWhere/_.whereのソースは、それが深い平等ではなく、厳密な等価を行い、です。あなたはどこ深い検索をしたい場合は、これは(最適化されていない、未テスト)十分であろう:

_.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 } }); 
関連する問題