Получение списка ключей ассоциативного массива

258

У меня есть ассоциативный массив в Javascript:

var dictionary = {
    "cats": [1,2,3,4,5], 
    "dogs": [6,7,8,9,10]
};

Как мне получить ключи этого словаря? т.е. я хочу

var keys = ["cats", "dogs"];

Отредактируйте 7 лет спустя: просто чтобы получить правильную терминологию - в Javascript не существует такого понятия, как «ассоциативный массив» - технически это просто objectобъект, и нам нужны именно объектные ключи.

Simon_Weaver
источник
Простой способ с lodash JS - lodash.com/docs#keys
Химический программист,
Спасибо за разъяснение терминологии! Вы можете сделать это немного больше в ярко-красных мигающих огнях?
Джо Филлипс
@Joe, я сделаю это первым результатом в Google для тебя, когда у меня будет шанс
Simon_Weaver

Ответы:

84

Ты можешь использовать: Object.keys(obj)

Пример:

var dictionary = {
  "cats": [1, 2, 37, 38, 40, 32, 33, 35, 39, 36],
  "dogs": [4, 5, 6, 3, 2]
};

// Get the keys
var keys = Object.keys(dictionary);

console.log(keys);

См. Ссылку ниже для поддержки браузера. Поддерживается в Firefox 4.20, Chrome 5, IE9. Ссылка ниже содержит фрагмент кода, который вы можете добавить, если Object.keys()он не поддерживается в вашем браузере.

https://developer.mozilla.org/en/JavaScript/Reference/Global_Objects/Object/keys

Роб де ла Круз
источник
Я переключаю это на принятый ответ сейчас. Только IE8 больше не поддерживает его (для которого доступен полифайл developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/… )
Simon_Weaver
382

Попробуй это:

var keys = [];
for (var key in dictionary) {
  if (dictionary.hasOwnProperty(key)) {
    keys.push(key);
  }
}

hasOwnPropertyнеобходим, потому что можно вставить ключи в объект-прототип dictionary. Но вы, как правило, не хотите, чтобы эти ключи были включены в ваш список.

Например, если вы делаете это:

Object.prototype.c = 3;
var dictionary = {a: 1, b: 2};

и затем сделайте for...inцикл dictionary, вы получите aи b, но вы также получите c.

JW.
источник
Не нужно объявлять "var keys = []", если только вам не нужно использовать его после цикла.
mzalazar
2
@mzalazar, лучше, иначе это будет глобальная переменная, что является плохой практикой.
00:00
@ b00t Я думаю, что, объявив переменную внутри цикла for ... она не будет установлена ​​в глобальном пространстве ... теперь вы заставили меня усомниться в хе-хе :)
mzalazar
2
@mzalazar, но вы не объявляете его ( ключи ) в любой момент, если вы просто используете keys.push(key);. Вы просто извлекаете (и, следовательно, объявляете это) из глобального пространства имен. :)
b00t
183
for (var key in dictionary) {
  // do something with key
}

Это за ... в заявлении .

wombleton
источник
1
Просто заметил, что должна быть двоеточие вместо запятой между "собаками" и массивом выше. Предположим, это связано с транскрипцией.
Уомблтон
68
Очень важно проверить, dictionary.hasOwnProperty(key)иначе вы можете получить методы из цепочки прототипов.
Tigraine
4
Из той же статьи: перебирает перечисляемые свойства объекта в произвольном порядке . Если порядок ключей важен, вам нужно что-то сделать, например поместить их в массив, отсортировать их, а затем использовать цикл for (), чтобы получить ключи из отсортированного массива для индексации исходного объекта.
mcmlxxxvi
1
Это, конечно, справедливо для оптимизации, пропустив проверку dictionary.hasOwnProperty, если вы можете быть уверены, что у объекта нет прототипа. Но важно знать о возможности наследования прототипа в этом контексте, так как словари JavaScript действительно являются объектами.
fixermark
16

Просто быстрое примечание, будьте осторожны с использованием for..in, если вы используете библиотеку (jQuery, prototype и т. Д.), Так как большинство из них добавляют методы к создаваемым объектам (включая словари).

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

Джесси
источник
3

Простой способ JQUERY.

Это то, что я использую
DictionaryObj как объект словаря javascript, который вы хотите пройти. значение, ключом конечно же является их имена в словаре.

 $.each(DictionaryObj, function (key, value) {
            $("#storeDuplicationList")
                .append($("<li></li>")
                .attr("value", key)
                .text(value));
        });
Exzile
источник
1
это требует jQuery (что хорошо), но вы забыли упомянуть об этом :-)
Simon_Weaver
@Exzile Имена аргументов в вашем определении функции очень запутаны. На api.jquery.com/jquery.each говорится, что обратным вызовом является Function (String propertyName, Object valueOfProperty). Ваши имена подразумевают обратное.
Крис
@ Крис, я обновлю это для тебя. Спасибо что подметил это.
Изгнание
0

Я в настоящее время использую ответ Роба де ла Круса

Object.keys(obj)

и в файле, загруженном ранее, у меня есть несколько строк кода, заимствованных из других источников в Интернете, которые охватывают случай старых версий интерпретаторов сценариев, в которых нет встроенных Object.keys.

if (!Object.keys) {
    Object.keys = function(object) {
        var keys = [];
        for (var o in object) {
            if (object.hasOwnProperty(o)) {
                keys.push(o);
            }
        }
        return keys;
    };
}

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

По сути, это ставит решение JW в функцию, когда Object.keys (obj) Роба де ла Круса недоступен изначально.

Иван
источник