如何获得一个关键的JavaScript对象的值?

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

984510 次浏览

没有可用的标准方法。你需要迭代,你可以创建一个简单的helper:

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之外使用这个函数,并将对象传递给它。

如前所述,迭代是必要的。例如,在现代浏览器中,你可以有:

var key = Object.keys(obj).filter(function(key) {return obj[key] === value})[0];
value包含您要查找的值。 说到这里,我可能会使用循环。

否则,你可以使用一个合适的“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);

我使用这个函数:

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

# EYZ0

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

或者,更简单的是—按您想要的顺序创建一个具有键和值的新对象,然后查找该对象。我们在使用上面的原型代码时发生了冲突。你不必在键周围使用String函数,那是可选的。

 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"

这确实假设键和值之间没有公共元素。

使用Underscore.js库:

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


(_.invert(hash))[1]; // => 'foo'

这是Underscorejs方法的一个小扩展,使用Lodash代替:

var getKeyByValue = function(searchValue) {
return _.findKey(hash, function(hashValue) {
return searchValue === hashValue;
});
}

< >强FindKey < / >强将匹配值的搜索并返回第一个键 如果你想要最后一个匹配,使用FindLastKey代替

我创建了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"

在两个方向上,键值映射的检索同样快。底层没有昂贵的对象/数组遍历,因此无论数据大小如何,平均访问时间都保持不变。

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

我通常推荐lodash而不是underscore。

如果你有,就好好利用。

如果没有,那么应该考虑使用lodash。反转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。倒转包装,大口吞咽

$ 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

https://lodash.com/

lodash和下划线的区别

https://github.com/gulpjs/gulp

给定input={"a":"x", "b":"y", "c":"x"}

  • 使用第一个值(例如output={"x":"a","y":"b"}):

input = {
"a": "x",
"b": "y",
"c": "x"
}
output = Object.keys(input).reduceRight(function(accum, key, i) {
accum[input[key]] = key;
return accum;
}, {})
console.log(output)

  • 使用最后一个值(例如output={"x":"c","y":"b"}):

input = {
"a": "x",
"b": "y",
"c": "x"
}
output = Object.keys(input).reduce(function(accum, key, i) {
accum[input[key]] = key;
return accum;
}, {})
console.log(output)

  • 获取每个值的键数组(例如output={"x":["c","a"],"y":["b"]}):

input = {
"a": "x",
"b": "y",
"c": "x"
}
output = Object.keys(input).reduceRight(function(accum, key, i) {
accum[input[key]] = (accum[input[key]] || []).concat(key);
return accum;
}, {})
console.log(output)

如果你正在使用下划线Lodash库,你可以使用_.findKey函数:

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'

保持你的< em > < / em >原型干净。

function val2key(val,array){
for (var key in array) {
if(array[key] == val){
return key;
}
}
return false;
}

例子:

var map = {"first" : 1, "second" : 2};
var key = val2key(2,map); /*returns "second"*/

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'

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

好像这个问题还没有被打得稀烂似的……

这里有一个,不管它给你带来了什么好奇心……

如果你确定你的对象将只有字符串值,你可能真的会用尽自己来想象这个实现:

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

也许这里有一些有用的东西……

希望这能让你开心。

Non-iteratable解决方案

主要功能:

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"

这里有一个Lodash解决方案,适用于flat key =>值对象,而不是嵌套对象。公认的答案建议使用_.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="https://cdnjs.cloudflare.com/ajax/libs/lodash.js/4.17.4/lodash.min.js"></script>

下划线js解决方案

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}

真的很简单。

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"

保持简单!

你不需要通过复杂的方法或库来过滤对象,Javascript有一个内置的函数,叫做Object.values

例子:

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

以下是我的解决方案:

例如,我假设我们有一个包含三个值对的对象:

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(数组,value),它接受两个参数,一个是对象,一个是你正在寻找的键的值。因此,该方法是可重用的,您不需要每次都手动迭代对象,只需为该函数传递两个参数。

# EYZ0方法:

Object.fromEntries(Object.entries(a).map(b => b.reverse()))['value_you_look_for']

最短一行

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

返回值为:

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

如果value为ArrayObject:

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

没有看到以下内容:

const obj = {
id: 1,
name: 'Den'
};


function getKeyByValue(obj, value) {
return Object.entries(obj).find(([, name]) => value === name);
}


const [ key ] = getKeyByValue(obj, 'Den');
console.log(key)
  

这为我获得对象的键/值工作。

let obj = {
'key1': 'value1',
'key2': 'value2',
'key3': 'value3',
'key4': 'value4'
}
Object.keys(obj).map(function(k){
console.log("key with value: "+k +" = "+obj[k])
    

})

如果你有一个带有数组的值的对象。这里有一个很好的例子。让我们假设您希望根据所拥有的文件的扩展名显示一个图标。具有相同图标的所有扩展都在相同的对象值下。

注意:将这里的case包装在一个对象中要比使用大量case进行切换要好。

检查下面的代码片段(用es6编写),看看我们如何为特定的扩展返回特定的键。

我从这个git存储库得到了扩展列表

// Oject that contains different icons for different extentions
const icons = {
"music": ["mp3", "m4a", "ogg", "acc", "flac","m3u", "wav"],
"video": ["mp4","webm", "mkv", "avi", "mov", "m4v", "mpeg"],
"image": ["jpg", "gif", "png", "jpeg", "tif", "psd", "raw", "ico"],
"archives": ["zip", "rar", "tar", "dmg", "jar"],
"3d-files": ["3ds", "dwg", "obj", "dae", "skp", "fbx"],
"text": ["doc", "rtf", "txt", "odt", "tex"],
"vector-graphics":["ai", "svg"],
"pdf": ["pdf"],
"data": ["xml", "csv", "xls"]
}


const get_icon_Key =( icons_object,file_extention) => {
// For each key we chack if the value is contained in the list of values
let key = Object.keys(icons_object).find(
k=> icons[k].find(
// At this leve we check if the extention exist in the array of the specific object value ie. 'music', 'video' ...
icons_ext => icons_ext === file_extention)
// if we find it means this is the key we are looking for
? true: false);
return key
}


console.log(`The icon of for mp3 extention is: => ${get_icon_Key(icons,"mp3")}`)
console.log(`The icon of for mp4 extention is: => ${get_icon_Key(icons,"mp4")}`)

我知道我迟到了,但你觉得我今天做的EMCMAScript 2017解决方案怎么样?它处理多个匹配,因为如果两个键有相同的值会发生什么?这就是我创建这个小片段的原因。

当有一个匹配时,它只返回一个字符串,但当有几个匹配时,它返回一个数组。

let object = { nine_eleven_was_a_inside_job: false, javascript_isnt_useful: false }


// Complex, dirty but useful. Handle mutiple matchs which is the main difficulty.
Object.prototype.getKeyByValue = function (val) {
  

let array = [];
let array2 = [];
  

// Get all the key in the object.
for(const [key] of Object.entries(this)) {
if (this[key] == val) {
// Putting them in the 1st array.
array.push(key)
}
}
  

// List all the value of the 1st array.
for(key of array) {
// "If one of the key in the array is equal to the value passed in the function (val), it means that 'val' correspond to it."
if(this[key] == val) {
// Push all the matchs.
array2.push(key);
}
}
  

// Check the lenght of the array.
if (array2.length < 2) {
// If it's under 2, only return the single value but not in the array.
return array2[0];
} else {
// If it's above or equal to 2, return the entire array.
return array2;
}
}


/*


Basic way to do it wich doesn't handle multiple matchs.


let getKeyByValue = function (object, val) {
for(const [key, content] of Object.entries(object)) {
if (object[key] === val) {
return key
}
}
}
*/


console.log(object.getKeyByValue(false))

我们可以使用简单的函数来获取传递的值

const getKeyByValue = (object, value) => Object.keys(object).find(key => object[key] === value)

来到这里(2022年),寻找OP问题的近似变体。变化:

如何根据一个值找到一个对象键,其中键可以保存值的集合?

对于这个用例,从相等(===)切换到.includes():

const foo = ['a', 'b','c'];
const bar = ['x', 'y', 'z'];
const bat = [2, 5, 'z'];
const obj = {foo: foo, bar: bar, bat: bat};


const findMe = (v) => {
return Object.keys(obj).filter((k) => obj[k].includes(v))
}


findMe('y') // ['bar']
findMe('z') // ['bar', 'bat']