使用数组反向查找对象
Reverse lookup object with array
假设我有一个像这样的对象
resourceMap = {
"a": [0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10],
"b": [11, 12],
"c": [21, 23],
"d": [54, 55, 56, 57, 510]
};
判断resourceId = 21
是否为"c"
的最佳方法是什么?
我们不知道钥匙的名称或钥匙的数量。它只匹配一次:意味着21
将只属于一个密钥"c"
。
我正在考虑循环使用所有键并执行indexOf()
,但我觉得它不够"优雅"。
我可以使用Undercore,但尽量避免使用Angular或jQuery,或者只是普通的Javascript。
在JavaScript中为对象提供数字属性名是完全可以接受的。我们可以利用这一点来构建第二个对象,以反向映射所有内容。这将使查找成本低廉。
var reverseMap = {};
for(var propName in resourceMap)
{
var numsArr = resourceMap[propName];
numsArr.forEach(function(num){
reverseMap[num]=propName;
});
}
console.log(reverseMap[54]); //'d'
http://jsfiddle.net/y11sbgbv/
构建反向映射也可以更"功能性"地完成(例如,不使用副作用),如下所示:
var reverseMap2 = Object.keys(resourceMap).reduce((acc, propName) =>
resourceMap[propName].reduce((a, num) => {
a[num] = propName;
return a;
}, acc), {});
预处理为不同的查找表
var revMap = []; // or var revMap = {};
Object.keys(resourceMap).forEach(function(key) {
resourceMap[key].forEach( function (ind) {
revMap[ind] = key;
});
});
console.log(revMap[21])
或按需查询:
resourceMap = { "a": [0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10], "b": [11, 12], "c": [21, 23], "d": [54, 55, 56, 57, 510] };
function findMapKey (map, ind) {
var match = null;
Object.keys(map).some(function(key) {
var test = map[key].indexOf(ind)!==-1;
if (test) {
match = key;
}
return test;
});
return match;
}
console.log(findMapKey(resourceMap, 21));
它看起来像是对值进行了排序,所以您可以首先查看每个数组的最新值是否大于您要搜索的值,一旦找到,就查找值本身。
for(var propName in resourceMap)
{
var array = resourceMap[propName];
var lastNum = array[array.length-1];
if(lastNum == 21 || (lastNum > 21 && array.indexOf(21) > -1))
{
console.log(propName)
break;
}
}
除非您正在处理大量数据,否则您的想法很好:
var resourceMap = {
"a": [0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10],
"b": [11, 12],
"c": [21, 23],
"d": [54, 55, 56, 57, 510]
};
/**
* @return resource's group, or false if no matching group is found
*/
var getResourceGroup = function(res) {
for (var i in resourceMap) {
if (resourceMap[i].indexOf(res) > -1) {
return i;
}
}
return false;
}
console.log(getResourceGroup(21));
我理解对优雅的渴望,我在自己的作品中也努力做到这一点。但这很简单,很容易得到支持,而且假设您的数据集不是很大,速度也相对较快。
如果您要多次调用该函数,那么第一次通过该函数构建反向字典可能是值得的,这样您就可以使用它来加快未来的查找速度。问题是,如果确实有大量数据,那么您将在内存中构建一个相当大的数据结构。也许没什么大不了的,但值得考虑。
尝试
resourceMap = {
"a": [0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10],
"b": [11, 12],
"c": [21, 23],
"d": [54, 55, 56, 57, 510]
};
var getKey = function(val, _key) {
$.each(resourceMap, function(k, v) {
if ($.inArray(val, v) != -1) {
_key = k
}
})
return _key
};
getKey(21)
jsfiddlehttp://jsfiddle.net/guest271314/gbnzmq51/
相关文章:
- Javascript:根据对象的嵌套数组中的值,在数组中查找对象的索引
- 正在数组中查找对象
- 在prototypejs中查找对象的类
- 通过知道对象的id在JSON中查找对象
- Javascript在JSON中查找对象(我使用Angular)
- 查找对象数组是否包含其中一个标记的最快方法
- 如何将查找对象值传递到FetchXml查询中
- JavaScript-通过类似的属性查找对象,并将其推送到一个新的数组中
- 通过匹配 - Javascript/AngularJS 中的参数来查找对象
- 正在查找对象集合的最大值
- 根据Angular JS中的属性值在列表中查找对象
- 在下划线中的对象中查找对象中的重复项
- 如何使用正则表达式查找对象成员名称
- 通过包含的字符串查找对象
- 在 Firebase 中通过对象的唯一 id 查找对象
- 在 javascript 中查找对象的类型
- 查找对象树中特定字段值的所有出现
- 如何在javascript数组中按键和值查找对象的索引
- 使用 Javascript/React.js 查找对象的数组索引
- 查找对象数组(Angularjs)中是否存在值