使用数组反向查找对象

时间:2014-10-07 17:10:22

标签: javascript jquery json angularjs

如果我有这样的对象,请说明

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()

我正在考虑循环遍历所有键并执行{{1}},但我感觉不到它的优雅"够了。

我可以使用Underscore但是尽量避免使用Angular或jQuery或者只是使用vanilla Javascript。

5 个答案:

答案 0 :(得分:7)

在JavaScript中使用numeric property names for objects是完全可以接受的。我们可以利用它来构建第二个反向映射所有内容的对象。这将使查找成本低廉。

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/

构建reverseMap也可以做得更多"功能性" (例如,不使用副作用)如下:

var reverseMap2 = Object.keys(resourceMap).reduce((acc, propName) =>          
  resourceMap[propName].reduce((a, num) => {
    a[num] = propName;
    return a;
  }, acc), {});

答案 1 :(得分:3)

预处理到不同的查找表

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

答案 2 :(得分:0)

除非你正在处理大量数据,否则你的想法很好:



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




我理解对优雅的渴望,我也在自己的工作中努力。但这很简单,容易支持,并且假设您的数据集不是很大,相对快速。

如果你要多次调用该函数,那么第一次通过该函数构建反向字典可能是值得的,这样你就可以使用它来加速将来的查找。需要注意的是,如果您有大量数据,那么您将在内存中构建一个相当大的数据结构。可能不是什么大问题,但值得考虑。

答案 3 :(得分:0)

看起来值已排序,因此您可以先查看每个数组的最新值是否大于您要搜索的值,找到后,查找值本身。

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

答案 4 :(得分:0)

尝试

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)

jsfiddle http://jsfiddle.net/guest271314/gbnzmq51/