admin管理员组文章数量:1414613
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"?
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"?
Share Improve this question asked Jan 2, 2015 at 11:04 CristianCCristianC 3013 silver badges11 bronze badges 4- 1 There's nothing built-in that searchest by object values. You have to write a loop. – Barmar Commented Jan 2, 2015 at 11:07
- Does the object contain exactly two names and two ids? – RobG Commented Jan 2, 2015 at 11:08
- Yes, two names and two ids, but they might be in different keys (id1 or id2/ name1 or name2) – CristianC Commented Jan 2, 2015 at 11:11
- So given either a name or id value, you want to get back the other id and name? – RobG Commented Jan 2, 2015 at 11:29
5 Answers
Reset to default 1var 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;
}
}
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' }
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).
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 bees 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).
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/b1yL28at/
本文标签: arraysJavascript get corresponding keyvalue from objectStack Overflow
版权声明:本文标题:arrays - Javascript get corresponding keyvalue from object - Stack Overflow 内容由网友自发贡献,该文观点仅代表作者本人, 转载请联系作者并注明出处:http://www.betaflare.com/web/1745153489a2645026.html, 本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如发现本站有涉嫌抄袭侵权/违法违规的内容,一经查实,本站将立刻删除。
发表评论