Reputation: 301
I have an object which might look like this:
var nicknames = []
nicknames.push({id:"100", name:"john", id2:"200", name2:"max"});
but the object might also look like this:
nicknames.push({id:"200", name:"max", id2:"100", name2:"john"});
so key and values might be switched.
How can I get the name and id "john" and "100" if providing name of "max" or id of "200"?
Upvotes: 4
Views: 2152
Reputation: 7862
Maybe this will be useful for you.
var nicknames= [ {id:"100", nickname:"John"}, {id:"200", nickname:"Michael"} ];
function getByName(arr, value) {
for (var i=0, iLen=arr.length; i<iLen; i++) {
if (arr[i].nickname == value) return arr[i];
}
}
var object = getByName(nicknames, "John");
// Will show '100'
alert(object.id);
You can see this in action here: http://jsfiddle.net/b1yL28at/
Upvotes: 1
Reputation: 367
In you keep this data representation, you'll have to loop over your entire array, which is inefficient.
I think you should (if you can) change your data representation and opt for an associative array, where keys are pairs id-name and values are nicknames. This way it becomes easy and efficient to find matches.
Or, maybe even better because it reduces redundancy, two associative arrays: the first one for id/names; the second for nickname matches (keys are ids and values are ids as well).
Upvotes: 1
Reputation: 147363
If the data structure is as described and here are exactly two names and IDs, and the name and ID sets are unique in each object, then the following should do the job:
var nicknames = [{id:"100", name:"john", id2:"200", name2:"max"},
{id:"300", name:"tim", id2:"400", name2:"fred"}];
function getOther(nameOrId) {
var nickname;
for (var i=0, iLen=nicknames.length; i<iLen; i++) {
nickname = nicknames[i];
if (nickname.id == nameOrId || nickname.name == nameOrId) {
return [nickname.id2, nickname.name2];
}
if (nickname.id2 == nameOrId || nickname.name2 == nameOrId) {
return [nickname.id, nickname.name];
}
}
}
console.log(getOther('max')); // ["100", "john"]
console.log(getOther('100')); // ["200", "max"]
console.log(getOther('400')); // ["300", "tim"]
It just looks for a match with the name or id within a nickname pair and if finds one, returns the other. It could be made more generic.
If you want to keep Douglas Crockford happy and avoid the loop by using an ES5 feature, then:
function getOther(nameOrId) {
var result;
nicknames.some(function (nickname) {
if (nickname.id == nameOrId || nickname.name == nameOrId) {
return result = [nickname.id2, nickname.name2];
}
if (nickname.id2 == nameOrId || nickname.name2 == nameOrId) {
return result = [nickname.id, nickname.name];
}
});
return result;
}
But I don't see the point, it's exactly the same number of lines of code and no clearer (IMHO of course).
Upvotes: 1
Reputation: 239443
If you are going to do more lookups, then the best solution I could think of is to build an inverse map, like this
var nicknames = []
nicknames.push({
id: "100",
name: "john",
id2: "200",
name2: "max"
});
var idIndex = {},
nameIndex = {};
nicknames.forEach(function(currentNickName) {
idIndex[currentNickName.id] = {
id: currentNickName.id2,
name: currentNickName.name2
};
idIndex[currentNickName.id2] = {
id: currentNickName.id,
name: currentNickName.name
};
nameIndex[currentNickName.name] = {
id: currentNickName.id2,
name: currentNickName.name2
};
nameIndex[currentNickName.name2] = {
id: currentNickName.id,
name: currentNickName.name
};
});
And then would look like
console.log(nameIndex, idIndex);
this
{ john: { id: '200', name: 'max' }, max: { id: '100', name: 'john' } }
{ '100': { id: '200', name: 'max' }, '200': { id: '100', name: 'john' } }
And then you can search like this
console.log(nameIndex["max"]);
// { id: '100', name: 'john' }
console.log(nameIndex["john"]);
// { id: '200', name: 'max' }
console.log(idIndex["100"]);
// { id: '200', name: 'max' }
console.log(idIndex["200"]);
// { id: '100', name: 'john' }
Upvotes: 1
Reputation: 780734
var found_name, found_id;
for(var i = 0; i < nicknames.length; i++) {
var nn = nicknames[i];
if (nn.name == "max" || nn.id = "200") {
found_name = nn.name2;
found_id = nn.id2;
break;
} else if (nn.name2 == "max" || nn.id2 = "200") {
found_name = nn.name;
found_id = nn.id;
break;
}
}
Upvotes: 1