jQuery/Javascript index into collection/map by object property?
I have the following Javascript defining an array of countries and their states...
var countryStateMap = [{"CountryCode":"CA","Name":"Canada","States":[{"StateCode":"S!","CountryCode":"CA","Name":"State 1"},{"StateCode":"S2","CountryCode":"CA","Name":"State 2"}]},"CountryCode":"US","Name":"Un开发者_开发问答ited States","States":[{"StateCode":"S1","CountryCode":"US","Name":"State 1"}]}];
Based on what country the user selects, I need to refresh a select box's options for states from the selected Country object. I know I can index into the country collection with an int index like so...
countryStateMap[0].States
I need a way to get the Country by CountryCode property though. I know the following doesn't work but what I would like to do is something like this...
countryStateMap[CountryCode='CA'].States
Can this be achieved without completely rebuilding my collection's structure or iterating over the set each time to find the one I want?
UPDATE: I accepted mVChr's answer because it worked and was the simplest solution even though it required a second map.
The solution we actually ended up going with was just using the country select box's index to index into the collection. This worked because our country dropdown was also being populated from our data structure. Here is how we indexed in...
countryStateMap[$('#country').attr("selectedIndex")]
If you need to do it any other way, use any of the below solutions.
One thing you could do is cache a map so you only have to do the iteration once:
var csmMap = {};
for (var i = 0, cl = countryStateMap.length; i < cl; i++) {
csmMap[countryStateMap[i].CountryCode] = i;
}
Then if countryCode = 'CA'
you can find its states like:
countryStateMap[csmMap[countryCode]].States
countryStateMap.get = function(cc) {
if (countryStateMap.get._cache[cc] === void 0) {
for (var i = 0, ii = countryStateMap.length; i < ii; i++) {
if (countryStateMap[i].CountryCode === cc) {
countryStateMap.get._cache[cc] = countryStateMap[i];
break;
}
}
}
return countryStateMap.get._cache[cc];
}
countryStateMap.get._cache = {};
Now you can just call .get("CA")
like so
countryStateMap.get("CA").States
If you prefer syntatic sugar you may be interested in underscore which has utility methods to make this kind of code easier to write
countryStateMap.get = _.memoize(function(cc) {
return _.filter(countryStateMap, function(val) {
val.CountryCode = cc;
})[0];
});
_.memoize
, _.filter
love your local jQuery:
small little function for you:
getByCountryCode = function(code){var res={};$.each(countryStateMap, function(i,o){if(o.CountryCode==code)res=o;return false;});return res}
so do this then:
getByCountryCode("CA").States
and it returns:
[Object, Object]
精彩评论