Richard
Richard

Reputation: 32909

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 all 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!

Upvotes: 0

Views: 530

Answers (4)

Tomalak
Tomalak

Reputation: 338228

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.

Upvotes: 0

gion_13
gion_13

Reputation: 41533

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;
}

Upvotes: 0

nnnnnn
nnnnnn

Reputation: 150040

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] }

Upvotes: 1

user880625
user880625

Reputation: 246

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

Upvotes: 0

Related Questions