7

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

1

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

5 ответ(ов)

11

Вам нужно получить ключ из объекта по заданному значению? В таком случае, можете использовать следующий код на JavaScript:

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

Этот код использует метод Object.keys(), чтобы получить массив всех ключей объекта, а затем применяет метод find() для поиска первого ключа, значение которого соответствует заданному.

Например, если у вас есть объект:

const map = {"first" : "1", "second" : "2"};

Вы можете вызвать функцию следующим образом:

console.log(getKeyByValue(map, "2")); // Выведет: "second"

Обратите внимание, что функция возвращает только первый найденный ключ, который соответствует значению. Если значение не найдено, функция вернёт undefined. Этот подход написан на ES6 и не использует мутации прототипов или внешние библиотеки.

1

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

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);  // возвращает 'key1'

Одно замечание: даже если вышеуказанный код работает, в целом это плохая идея — расширять .prototype любого встроенного или нативного объекта. Я сделал это здесь, потому что это хорошо иллюстрирует проблему. В любом случае, вам, вероятно, стоит использовать эту функцию вне .prototype и передавать объект в качестве аргумента.

1

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

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

Где value — это значение, которое вы ищете. Тем не менее, я бы, вероятно, использовал цикл.

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

UPDATE 2018

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

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

Конечно, это также может быть функцией:

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

Самые короткие однострочные решения

Чтобы получить первый ключ с заданным значением:

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

Чтобы вернуть все ключи, соответствующие значению:

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

Если значение — это Array или Object:

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

Вы можете использовать метод _.findKey из библиотеки Lodash для поиска ключа в объекте на основе определенных условий. В вашем случае, если вы хотите найти ключ пользователя с возрастом 1 и статусом активности true, вы можете сделать это следующим образом:

var users = {
  'barney':  { 'age': 36, 'active': true },
  'fred':    { 'age': 40, 'active': false },
  'pebbles': { 'age': 1,  'active': true }
};

_.findKey(users, { 'age': 1, 'active': true });
// → 'pebbles'

Этот код ищет ключ в объекте users, где свойства совпадают с указанными значениями. В результате он возвращает строку 'pebbles', так как именно этот ключ соответствует указанному критерию (возраст 1 и активность true). Метод _.findKey удобен тем, что при помощи него можно легко находить ключи на основании значений свойств, обеспечивая при этом чистоту и удобочитаемость кода.

Чтобы ответить на вопрос, пожалуйста, войдите или зарегистрируйтесь