如何通过值获取 JavaScript 对象中的键?

IT技术 javascript object
2021-01-29 09:01:57

我有一个非常简单的 JavaScript 对象,我将其用作关联数组。是否有一个简单的函数允许我获取值的键,或者我是否必须迭代对象并手动找到它?

6个回答
function getKeyByValue(object, value) {
  return Object.keys(object).find(key => object[key] === value);
}

ES6,没有原型突变或外部库。

例子,

function getKeyByValue(object, value) {
  return Object.keys(object).find(key => object[key] === value);
}


const map = {"first" : "1", "second" : "2"};
console.log(getKeyByValue(map,"2"));

@BenWainwright:维护一个BiMap或等价物(Alethes 的答案)通常是解决更广泛问题的有效 O(1) 方法,但即使是一次性的,也至少可以for in在找到匹配项时进行迭代和中断,而不是创建一个完整的提前输入一系列键,导致最好的情况比最坏的情况好。也就是说,O(position) 而不是 O(size)。(此页面上唯一比 O(size) 更糟糕的答案是愚蠢的 JSON 答案。)
2021-03-18 09:01:57
如果多个键具有相同的值,请使用过滤器而不是查找 function getKeyByValue(object, value) { return Object.keys(object).filter(key => object[key] === value); }
2021-03-22 09:01:57
哈哈。这并不慢,它是 O(n),这几乎是最好的运行时。
2021-03-24 09:01:57
根据实现,这可能需要O(n)空间,因为keys()实现了键集。
2021-03-29 09:01:57
好吧,如果你不支持 IE11 的话真的很干净 :-) 如果是这样,你需要一个 polyfill
2021-03-30 09:01:57

没有可用的标准方法。您需要迭代,您可以创建一个简单的帮助程序:

Object.prototype.getKeyByValue = function( value ) {
    for( var prop in this ) {
        if( this.hasOwnProperty( prop ) ) {
             if( this[ prop ] === value )
                 return prop;
        }
    }
}

var test = {
   key1: 42,
   key2: 'foo'
};

test.getKeyByValue( 42 );  // returns 'key1'

一个警告:即使上述方法有效,扩展任何主机或本机对象的.prototype. 我在这里这样做是因为它非常适合这个问题。无论如何,您可能应该在 之外使用此函数.prototype并将对象传递给它。

哦,伙计,如果值不存在,我喜欢这如何悄悄地返回 undefined 。做得好。此外,只是一个兴趣点,这将执行 O(n),因此如果对象具有大量属性(例如大城市中的人员列表及其地址),您可能需要更有效的搜索。也许排序值和二进制搜索?诶?
2021-03-10 09:01:57
实际上,如果您知道 for-in 循环沿着属性链向下,这意味着“for(var key in obj)”在某些时候会给您“getKeyByValue”作为“key”之类的东西。
2021-03-12 09:01:57
非常感谢,当我看到坏主意时,我想知道为什么然后我搜索了这个并在这里添加了这个答案增强和广泛阅读。stackoverflow.com/questions/3085240/...
2021-03-17 09:01:57
我认为将其转换为字符串会更好地修复类型错误,如果需要,只需将.toString()类似obj[ key ].toString()和值添加到值中...
2021-03-18 09:01:57
@jAndy 不是 ===,而是 ==。您的代码不适用于 ===。它返回未定义。
2021-03-27 09:01:57

如前所述,需要迭代。例如,在现代浏览器中,您可以:

var key = Object.keys(obj).filter(function(key) {return obj[key] === value})[0];

Wherevalue包含您要查找的值。说到这里,我可能会使用循环。

否则你可以使用一个合适的“hashmap”对象——在 JS 中有几个实现——或者你自己实现。

2018 年更新

六年过去了,但我仍然在这里得到一些投票,所以我觉得一个更现代的解决方案 - 适用于现代浏览器/环境 - 应该在答案本身中提及,而不仅仅是在评论中:

const key = Object.keys(obj).find(key => obj[key] === value);

当然也可以是函数:

const getKeyByValue = (obj, value) => 
        Object.keys(obj).find(key => obj[key] === value);
至于箭头,它来了,我在等它:)or当然!它最近才被评估和接受(我认为还没有人实施它)。它的作用是找到匹配谓词的数组的第一个元素并返回它。所以[1,2,3,4].or(x=>x>2)会回来3[1,2,3,4,5].or(x=>x<3)会回来1类似于 C# 的 FirstOrDefault :)
2021-03-11 09:01:57
不幸的是,箭头函数还不是任何“现代”浏览器,所以目前它有点无用——我在 Firefox Nightly 的 jetpack 中使用它,它将在 Firefox 22 中使用。无论如何,我不知道任何or数组的方法,我不清楚它在这里的目的:我会欣赏一些额外的细节!:)
2021-03-25 09:01:57
ES6: Object.keys(obj).or(o=>o[key] === value)
2021-03-31 09:01:57
是的,箭头来了,但它需要被广泛使用——除非像我一样,有人在开发特定的引擎。我不知道 ES6 的新提案,我认为已经很接近了:你有关于该or方法的链接吗?从您提到的内容来看,它似乎返回与谓词“或”数组本身匹配的项目?
2021-04-02 09:01:57
后面提到的@sg552or已重命名。我相信现在你应该使用find
2021-04-02 09:01:57

使用Underscore.js库:

var hash = {
  foo: 1,
  bar: 2
};

(_.invert(hash))[1]; // => 'foo'
仅供寻求解决方案的任何人使用,该解决方案将为您提供与值匹配的所有键:这行不通。
2021-03-14 09:01:57
_.invert 在值包含对象的情况下不起作用,因为默认字符串序列化发生冲突。你可能会使用这个可憎的东西:_.chain(hash).pairs().findWhere({1: 1}).value()[0]
2021-03-15 09:01:57
下划线键也可以使用。underscorejs.org/#keys _.keys({一: 1, 二: 2, 三: 3}); => [“一”、“二”、“三”]
2021-03-20 09:01:57
这不应该是公认的答案,它通过一个强制改变当前代码结构的库提出了一个解决方案
2021-03-25 09:01:57
@GeorgeJempty 不是每个人都想加载一个 5kb 的库来进行简单的密钥查找;)
2021-04-05 09:01:57

ES6+ 一个内胆

let key = Object.keys(obj).find(k=>obj[k]===value);

返回具有值的所有键:

let keys = Object.keys(obj).filter(k=>obj[k]===value);