Neater way to filter Object containing other Objects by value
I've got a JavaScript object that looks like this:
var options = {
'user1' : { 'house1' : ["lat1", "lng1"] },
'user2' : { 'house2' : ["lat2", "lng2"] },
'user3' : { 'house1' : ["lat3", "lng3"] }
};
Say I want to look up a开发者_运维技巧ll the users associated with house1
, and return an array of their usernames and their positions.
What's the clearest and most efficient way to do this?
Currently I've written a rather unwieldy custom lookup, as follows:
function returnByValues(options, housenum):
var results = [];
for (var username in options) {
var properties = options[username];
for (var housekey in properties) {
if (housekey === housenum) {
var result = {};
result[username] = properties;
results.push(result);
}
}
}
return results;
Is there a neater way? It's not exactly readable code!
I don't think you need the middle loop, assuming each user is only associated with one house as per your example. So:
function returnByValues(options, housenum):
var results = [];
for (var username in options) {
var properties = options[username];
if (housenum in properties) {
var result = {};
result[username] = properties;
results.push(result);
}
}
return results;
}
You don't often see the if (housenum in properties)
syntax, but it's a more elegant equivalent of if (properties[housenum] != undefined)
.
By the way, your code:
result[username] = properties;
gives result == {"user1" : { 'house1' : [lat, lng] } }
- is that your intention? Because your description of what you want was "an array of their usernames and their positions" which I would take to be this:
result[username] = properties[housenum];
giving result == {"user1" : [lat, lng] }
I guess you search for sth like this: filteredArray = array.filter( ... return a.xyz == b.xyz )
If so, take a look at this: http://www.tutorialspoint.com/javascript/array_filter.htm
function returnByValues(options, housenum){
var results = [];
for (var username in options)
if(housenum in options[username])
results.push(function(){
var obj={};
obj[username] = options[username];
return obj;
});
return results;
}
If you wanted to use linq.js, you could do things along the lines of
function returnByValues(users, house) {
return Enumerable.From(users).Where("'" + house + "' in $.Value")
.ToObject("$.Key", "$.Value");
}
where this
var searchResult = returnByValues(options, "house1");
/* yields:
{
"user1": {
"house1": ["lat1", "lng1"]
},
"user3": {
"house1": ["lat3", "lng3"]
}
}
*/
Look at a working example on jsFiddle.
精彩评论