如何通过它的值获得一个JavaScript对象的关键?
我有一个非常简单的JavaScript对象,我用它作为关联数组。 有一个简单的函数,可以让我获得一个值的关键,还是我必须迭代对象,并找出它手动?
lodash的方式https://lodash.com/docs#findKey
var users = { 'barney': { 'age': 36, 'active': true }, 'fred': { 'age': 40, 'active': false }, 'pebbles': { 'age': 1, 'active': true } }; _.findKey(users, { 'age': 1, 'active': true }); // → 'pebbles'
没有可用的标准方法。 你需要迭代,你可以创建一个简单的帮助器:
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
之外使用这个函数,然后把对象传递给它。
function getKeyByValue(object, value) { return Object.keys(object).find(key => object[key] === value); }
ES6,没有原型突变或外部库。
与Underscore.js
var hash = { foo: 1, bar: 2 }; (_.invert(hash))[1]; // => 'foo'
如上所述,迭代是必要的。 例如,在现代浏览器中,您可以拥有:
var key = Object.keys(obj).filter(function(key) {return obj[key] === value})[0];
value
包含您正在寻找的价值。 说,我可能会使用一个循环。
否则,您可以使用适当的“hashmap”对象 – 在JS中有几个实现 – 或者由您自己实现。
我使用这个功能:
Object.prototype.getKey = function(value){ for(var key in this){ if(this[key] == value){ return key; } } return null; };
用法:
// 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
如果你有(或者想要)对underscore.js的依赖,你可以使用findKey函数。 例如,
var test = { key1: 42, key2: 'foo' };
ES6
_.findKey(test, (val) => val === 42);
ES5
_.findKey(test, function(val) { return val === 42; });
function extractKeyValue(obj, value) { return Object.keys(obj)[Object.values(obj).indexOf(value)]; }
由编译器提取编译后的密钥名称
更性感的版本,但使用未来的Object.entries
功能
function objectKeyByValue (obj, val) { return Object.entries(obj).find(i => i[1] === val); }
保持你的原型清洁。
function val2key(val,array){ for (var key in array) { this_val = array[key]; if(this_val == val){ return key; break; } } }
例:
var map = {"first" : 1, "second" : 2}; val2key(2,map); /*returns "second"*/
我创建了bimap库( https://github.com/alethes/bimap ),它实现了一个功能强大,灵活和高效的JavaScript双向地图界面。 它没有依赖关系,可以在服务器端(在Node.js中,可以使用npm install bimap
)和浏览器(通过链接到lib / bimap.js )使用。
基本操作非常简单:
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"
键值映射的检索在两个方向上都是同样快的。 在引擎盖下没有昂贵的对象/数组遍历,所以无论数据的大小如何,平均访问时间都保持不变。
不可迭代的解决方案
主功能:
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 }
具有键和值的对象:
var greetings = { english : "hello", ukranian : "привіт" };
测试:
keyByValue("привіт"); // => "ukranian"
或者,更容易 – 用你想要的顺序用键和值创建一个新的对象,然后查找这个对象。 我们使用上面的原型代码发生冲突。 您不必在密钥周围使用字符串函数,这是可选的。
newLookUpObj = {}; $.each(oldLookUpObj,function(key,value){ newLookUpObj[value] = String(key); });
由于这些值是唯一的,所以应该可以将这些值作为附加的一组键来添加。 这可以通过以下快捷方式来完成。
var foo = {}; foo[foo.apple = "an apple"] = "apple"; foo[foo.pear = "a pear"] = "pear";
这将允许通过键或值进行检索:
var key = "apple"; var value = "an apple"; console.log(foo[value]); // "apple" console.log(foo[key]); // "an apple"
这确实假设键和值之间没有共同的元素。
仿佛这个问题还没有被打到一个纸浆…
这里有一个只是为了好奇心带给你…
如果你确定你的对象只有字符串值,你可能会用尽自己的想法来实现这个实现:
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]);
也许有一些有用的建立在这里…
希望这让你感到有趣。
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; }
我通常建议lodash而不是下划线。
如果你有它,使用它。
如果你不这样做,那么你应该考虑使用lodash.invert npm包,这是非常小的。
以下是如何使用gulp进行测试的方法:
1)使用以下内容创建一个名为gulpfile.js的文件:
// 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
$ npm i --save lodash.invert && npm install gulp
3)测试它的工作原理:
$ 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
lodash和下划线之间的区别
给定input={"a":"x", "b":"y", "c":"x"}
…
要使用第一个值(例如output={"x":"a","y":"b"}
): output=Object.keys(input).reduceRight(function(accum,key,i){accum[input[key]]=key;return accum;},{})
要使用最后一个值(例如: output={"x":"c","y":"b"}
): output=Object.keys(input).reduce(function(accum,key,i){accum[input[key]]=key;return accum;},{})
为每个值获取一个键的数组(例如: output={"x":["c","a"],"y":["b"]}
): output=Object.keys(input).reduceRight(function(accum,key,i){accum[input[key]]=(accum[input[key]]||[]).concat(key);return accum;},{})
这是Underscorejs方法的一个小扩展,并使用Lodash代替:
var getKeyByValue = function(searchValue) { return _.findKey(hash, function(hashValue) { return searchValue === hashValue; }); }
FindKey将搜索并返回与该值匹配的第一个键 。
如果您想要最后的匹配,请改用FindLastKey 。
这是一个Lodash解决方案,它适用于flat key => value对象,而不是嵌套对象。 被接受的答案使用_.findKey
的建议适用于具有嵌套对象的对象,但在这种常见情况下不起作用。
这种方法反转对象,交换键的值,然后通过查找新的(反转)对象上的值来找到键。 如果没有找到键,那么返回false
,我更喜欢undefined
,但是可以在getKey()
中的_.get
方法的第三个参数中轻松地交换出来。
// 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' ) + '"' );
<script src="ajax/libs/lodash.js/4.17.4/lodash.min.js"></script>