Как получить ключ в объекте JavaScript по его значению?

У меня довольно простой объект JavaScript, который я использую как ассоциативный массив. Есть ли простая функция, позволяющая мне получить ключ для значения, или мне нужно выполнить итерацию объекта и найти его вручную?

Ответ 1

с библиотекой Underscore.js:

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

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

Ответ 2

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

Ответ 3

Нет стандартного метода. Вам нужно выполнить итерацию, и вы можете создать простой помощник:

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 и вместо этого передать объект в нее.

Ответ 4

Как сказано, итерация необходима. Например, в современном браузере вы можете иметь:

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

Ответ 5

Способ 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'

Ответ 6

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

Ответ 7

Я использую эту функцию:

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

Ответ 8

Очистите прототип .

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"*/

Ответ 9

Если вы работаете с библиотекой Underscore или 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'

Ответ 10

Нетерабельное решение

Основная функция:

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"

Ответ 11

Я создал бимап-библиотеку (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"

Получение сопоставления значений ключей одинаково быстро в обоих направлениях. Нет никаких дорогостоящих обходов объекта/массива под капотом, поэтому среднее время доступа остается постоянным независимо от размера данных.

Ответ 12

Поскольку значения уникальны, должно быть возможно добавить значения в качестве дополнительного набора ключей. Это можно сделать со следующим ярлыком.

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"

Это предполагает, что между ключами и значениями нет общих элементов.

Ответ 13

Или, еще проще - создайте новый объект с ключами и значениями в том порядке, в котором вы хотите, и посмотрите на этот объект. У нас были конфликты, используя коды прототипов выше. Вам не нужно использовать функцию String вокруг ключа, что необязательно.

 newLookUpObj = {};
 $.each(oldLookUpObj,function(key,value){
        newLookUpObj[value] = String(key);
    });

Ответ 14

Как будто этот вопрос не был избит пульпой...

Здесь просто для любопытства, которое оно приносит вам...

Если вы уверены, что ваш объект будет иметь только строковые значения, вы действительно можете исчерпать себя, чтобы вызвать эту реализацию:

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

Может быть, есть что-то полезное, чтобы оторваться отсюда...

Надеюсь, это вас забавляет.

Ответ 15

http://jsfiddle.net/rTazZ/2/

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

Ответ 16

Это небольшое расширение для метода Underscorejs и вместо этого использует Lodash:

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

FindKey будет искать и возвращать первый ключ, который соответствует значению.
Если вы хотите использовать последнее совпадение, вместо этого используйте FindLastKey.

Ответ 17

Обычно я рекомендую 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 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

https://lodash.com/

Различия между lodash и подчеркиванием

https://github.com/gulpjs/gulp

Ответ 18

Учитывая 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;},{})

Ответ 19

Здесь используется решение Lodash, которое работает для объекта flat key = > value, а не вложенного объекта. Принятое предложение ответа на использование _.findKey работает для объектов с вложенными объектами, но в этом распространенном случае это не работает.

Этот подход инвертирует объект, заменяет ключи для значений, а затем находит ключ, просматривая значение для нового (инвертированного) объекта. Если ключ не найден, возвращается false, который я предпочитаю над undefined, но вы можете легко поменять его на третий параметр метода _.get в getKey().

// Get an object 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>

Ответ 20

Вот мое решение в первую очередь:

Например, я предполагаю, что у нас есть объект, который содержит три пары значений:

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 (массив, значение), который принимает два параметра, которые являются объектом и значением ключа, который вы ищете. Таким образом, этот метод можно использовать повторно, и вам не нужно каждый раз вручную повторять объект, передавая только два параметра для этой функции.

Ответ 21

Подчеркни 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}

Ответ 22

Действительно просто.

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"

Ответ 23

ES6 методы:

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

Ответ 24

Еще один способ сделать это:

let key = ( Object.entries(obj).find(([k,v])=>v==value) || [] )[0];

Ответ 25

Будь проще!

Вам не нужно фильтровать объект с помощью сложных методов или библиотек, 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