How to get a key in a JavaScript object by its value?
我有一个非常简单的javascript对象,我将它用作关联数组。是否有一个简单的函数允许我获取一个值的键,或者我必须迭代该对象并手动找到它?
1 2 3 | function getKeyByValue(object, value) { return Object.keys(object).find(key => object[key] === value); } |
无原型突变或外部库。
例子,
1 2 3 4 5 6 7 | function getKeyByValue(object, value) { return Object.keys(object).find(key => object[key] === value); } const map = {"first" :"1","second" :"2"}; console.log(getKeyByValue(map,"2")); |
没有可用的标准方法。您需要迭代,并且可以创建一个简单的助手:
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 | 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' |
注意:即使上述方法有效,扩展任何主机或本机对象的
使用
1 2 3 4 5 6 | var hash = { foo: 1, bar: 2 }; (_.invert(hash))[1]; // => 'foo' |
如前所述,需要迭代。例如,在现代浏览器中,您可以有:
1 | var key = Object.keys(obj).filter(function(key) {return obj[key] === value})[0]; |
其中
否则,您可以使用一个适当的"hashmap"对象——在JS中有几个实现——或者由您自己实现。
更新2018
六年过去了,但我仍然在这里得到了一些投票,所以我觉得对于现代浏览器/环境来说,一个更现代的解决方案应该在答案中提到,而不仅仅是在评论中:
1 | const key = Object.keys(obj).find(key => obj[key] === value); |
当然,它也可以是一个函数:
1 2 | const getKeyByValue = (obj, value) => Object.keys(obj).find(key => obj[key] === value); |
洛达什之路https://lodash.com/docs findkey
1 2 3 4 5 6 7 8 | var users = { 'barney': { 'age': 36, 'active': true }, 'fred': { 'age': 40, 'active': false }, 'pebbles': { 'age': 1, 'active': true } }; _.findKey(users, { 'age': 1, 'active': true }); // → 'pebbles' |
1 2 3 | function extractKeyValue(obj, value) { return Object.keys(obj)[Object.values(obj).indexOf(value)]; } |
使闭包编译器提取编译后未知的密钥名
更性感的版本,但使用未来的
1 2 3 | function objectKeyByValue (obj, val) { return Object.entries(obj).find(i => i[1] === val); } |
我使用这个函数:
1 2 3 4 5 6 7 8 | Object.prototype.getKey = function(value){ for(var key in this){ if(this[key] == value){ return key; } } return null; }; |
用途:
1 2 3 4 5 6 7 8 9 10 11 12 13 | // ISO 639: 2-letter codes var languageCodes = { DA: 'Danish', DE: 'German', DZ: 'Bhutani', EL: 'Greek', EN: 'English', EO: 'Esperanto', ES: 'Spanish' }; var key = languageCodes.getKey('Greek'); console.log(key); // EL |
Keep your prototype clean.
1 2 3 4 5 6 7 8 | function val2key(val,array){ for (var key in array) { if(array[key] == val){ return key; } } return false; } |
例子:
1 2 | var map = {"first" : 1,"second" : 2}; var key = val2key(2,map); /*returns"second"*/ |
如果您使用的是下划线或lodash库,则可以使用.findkey函数:
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 | var users = { 'barney': { 'age': 36, 'active': true }, 'fred': { 'age': 40, 'active': false }, 'pebbles': { 'age': 1, 'active': true } }; _.findKey(users, function(o) { return o.age < 40; }); // => 'barney' (iteration order is not guaranteed) // The `_.matches` iteratee shorthand. _.findKey(users, { 'age': 1, 'active': true }); // => 'pebbles' // The `_.matchesProperty` iteratee shorthand. _.findKey(users, ['active', false]); // => 'fred' // The `_.property` iteratee shorthand. _.findKey(users, 'active'); // => 'barney' |
Non-iteratable solution
主要功能:
1 2 3 4 5 6 7 8 | var keyByValue = function(value) { var kArray = Object.keys(greetings); // Creating array of keys var vArray = Object.values(greetings); // Creating array of values var vIndex = vArray.indexOf(value); // Finding value index return kArray[vIndex]; // Returning key by value index } |
具有键和值的对象:
1 2 3 4 | var greetings = { english :"hello", ukranian :"прив?т" }; |
测试:
1 2 | keyByValue("прив?т"); // =>"ukranian" |
我创建了bimap库(https://github.com/alethes/bimap),它实现了一个强大、灵活和高效的javascript双向映射接口。它没有依赖关系,可以在服务器端(在node.js中,您可以使用
基本操作非常简单:
1 2 3 4 5 6 7 8 9 | var bimap = new BiMap; bimap.push("k","v"); bimap.key("k") // =>"v" bimap.val("v") // =>"k" bimap.push("UK", ["London","Manchester"]); bimap.key("UK"); // => ["London","Manchester"] bimap.val("London"); // =>"UK" bimap.val("Manchester"); // =>"UK" |
检索关键值映射在两个方向上都同样快速。引擎盖下没有昂贵的对象/数组遍历,因此无论数据大小如何,平均访问时间都保持不变。
由于这些值是唯一的,所以应该可以将这些值作为一组附加键进行添加。这可以通过以下快捷方式完成。
1 2 3 | var foo = {}; foo[foo.apple ="an apple"] ="apple"; foo[foo.pear ="a pear"] ="pear"; |
这将允许通过键或值进行检索:
1 2 3 4 5 | var key ="apple"; var value ="an apple"; console.log(foo[value]); //"apple" console.log(foo[key]); //"an apple" |
这确实假定键和值之间没有公共元素。
或者,更简单——创建一个新的对象,按照您想要的顺序使用键和值,然后对照该对象进行查找。我们在使用上面的原型代码时遇到了冲突。您不必在键周围使用字符串函数,这是可选的。
1 2 3 4 | newLookUpObj = {}; $.each(oldLookUpObj,function(key,value){ newLookUpObj[value] = String(key); }); |
好像这个问题还没有被打得一塌糊涂…
不管它带给你什么好奇心…
如果您确定您的对象将只有字符串值,那么您可能真的会耗尽自己的精力来调用这个实现:
1 2 3 4 5 6 7 8 9 10 11 12 | var o = { a: '_A', b: '_B', c: '_C' } , json = JSON.stringify(o) , split = json.split('') , nosj = split.reverse() , o2 = nosj.join(''); var reversed = o2.replace(/[{}]+/g, function ($1) { return ({ '{':'}', '}':'{' })[$1]; }) , object = JSON.parse(reversed) , value = '_B' , eulav = value.split('').reverse().join(''); console.log('>>', object[eulav]); |
也许这里有一些有用的东西…
希望这能让你开心。
http://jsfiddle.net/rtazz/2/
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 | var a = new Array(); a.push({"1":"apple","2":"banana"}); a.push({"3":"coconut","4":"mango"}); GetIndexByValue(a,"coconut"); function GetIndexByValue(arrayName, value) { var keyName =""; var index = -1; for (var i = 0; i < arrayName.length; i++) { var obj = arrayName[i]; for (var key in obj) { if (obj[key] == value) { keyName = key; index = i; } } } //console.log(index); return index; } |
这是对underlinejs方法的一个小扩展,并使用lodash代替:
1 2 3 4 5 | var getKeyByValue = function(searchValue) { return _.findKey(hash, function(hashValue) { return searchValue === hashValue; }); } |
findkey将搜索并返回与值匹配的第一个键。如果需要最后一个匹配,请改用findlastkey。
鉴于
使用第一个值(如
使用最后一个值(如
要获得每个值的键数组(例如
首先是我的解决方案:
例如,我假设我们有一个包含三个值对的对象:
1 2 3 4 5 6 7 8 9 10 11 12 | function findKey(object, value) { for (let key in object) if (object[key] === value) return key; return"key is not found"; } const object = { id_1:"apple", id_2:"pear", id_3:"peach" }; console.log(findKey(object,"pear")); //expected output: id_2 |
我们可以简单地编写一个findkey(数组,值),它接受两个参数,即一个对象和您要查找的键的值。因此,此方法是可重用的,您不需要每次通过仅为此函数传递两个参数来手动迭代对象。
这里有一个lodash解决方案,它适用于平面键=>值对象,而不是嵌套对象。接受的答案建议使用
此方法反转对象,交换值的键,然后通过查找新(反转)对象上的值来查找键。如果找不到密钥,则返回
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 | // Get an object's key by value var getKey = function( obj, value ) { var inverse = _.invert( obj ); return _.get( inverse, value, false ); }; // US states used as an example var states = { "AL":"Alabama", "AK":"Alaska", "AS":"American Samoa", "AZ":"Arizona", "AR":"Arkansas", "CA":"California", "CO":"Colorado", "CT":"Connecticut", "DE":"Delaware", "DC":"District Of Columbia", "FM":"Federated States Of Micronesia", "FL":"Florida", "GA":"Georgia", "GU":"Guam", "HI":"Hawaii", "ID":"Idaho", "IL":"Illinois", "IN":"Indiana", "IA":"Iowa", "KS":"Kansas", "KY":"Kentucky", "LA":"Louisiana", "ME":"Maine", "MH":"Marshall Islands", "MD":"Maryland", "MA":"Massachusetts", "MI":"Michigan", "MN":"Minnesota", "MS":"Mississippi", "MO":"Missouri", "MT":"Montana", "NE":"Nebraska", "NV":"Nevada", "NH":"New Hampshire", "NJ":"New Jersey", "NM":"New Mexico", "NY":"New York", "NC":"North Carolina", "ND":"North Dakota", "MP":"Northern Mariana Islands", "OH":"Ohio", "OK":"Oklahoma", "OR":"Oregon", "PW":"Palau", "PA":"Pennsylvania", "PR":"Puerto Rico", "RI":"Rhode Island", "SC":"South Carolina", "SD":"South Dakota", "TN":"Tennessee", "TX":"Texas", "UT":"Utah", "VT":"Vermont", "VI":"Virgin Islands", "VA":"Virginia", "WA":"Washington", "WV":"West Virginia", "WI":"Wisconsin", "WY":"Wyoming" }; console.log( 'The key for"Massachusetts" is"' + getKey( states, 'Massachusetts' ) + '"' ); |
1 | <script src="https://cdnjs.cloudflare.com/ajax/libs/lodash.js/4.17.4/lodash.min.js"> |
非常简单。
1 2 3 4 5 6 7 8 9 10 | const CryptoEnum = Object.freeze({ "Bitcoin": 0,"Ethereum": 1, "Filecoin": 2,"Monero": 3, "EOS": 4,"Cardano": 5, "NEO": 6,"Dash": 7, "Zcash": 8,"Decred": 9 }); Object.entries(CryptoEnum)[0][0] // output =>"Bitcoin" |
我通常推荐罗达什而不是下划线。
如果你有,就用它。
如果不这样做,那么您应该考虑使用lodash.invert NPM包,它非常小。
以下是如何使用Gulp测试它:
1)创建一个名为gulpfile.js的文件,内容如下:
1 2 3 4 5 6 7 8 9 10 11 12 | // Filename: gulpfile.js var gulp = require('gulp'); var invert = require('lodash.invert'); gulp.task('test-invert', function () { var hash = { foo: 1, bar: 2 }; var val = 1; var key = (invert(hash))[val]; // << Here's where we call invert! console.log('key for val(' + val + '):', key); }); |
2)安装Lodash.Invert包和Gulp
1 | $ npm i --save lodash.invert && npm install gulp |
3)测试其工作:
1 2 3 4 5 | $ gulp test-invert [17:17:23] Using gulpfile ~/dev/npm/lodash-invert/gulpfile.js [17:17:23] Starting 'test-invert'... key for val(1): foo [17:17:23] Finished 'test-invert' after 511 μs |
工具书类
网址:https://www.npmjs.com/package/lodash.invert
网址:https://lodash.com/
罗达什和下划线的区别
https://github.com/gulpjs/gulp
下划线JS解决方案
1 2 3 4 5 | let samplLst = [{id:1,title:Lorem},{id:2,title:Ipsum}] let sampleKey = _.findLastIndex(samplLst,{_id:2}); //result would be 1 console.log(samplLst[sampleKey]) //output - {id:2,title:Ipsum} |
保持简单!
您不需要通过复杂的方法或libs来过滤对象,javascript有一个内置的函数object.values。
例子:
1 2 3 4 5 6 7 8 | let myObj = {jhon: {age: 20, job: 'Developer'}, marie: {age: 20, job: 'Developer'}}; function giveMeTheObjectData(object, property) { return Object.values(object[property]); } giveMeTheObjectData(myObj, 'marie'); // => returns marie: {} |
这将返回对象属性数据。
工具书类
https://developer.mozilla.org/pt-br/docs/web/javascript/reference/global_objects/object/values