Javascript: использование кортежей в качестве словарных ключей - PullRequest
28 голосов
/ 15 сентября 2009

У меня есть ситуация, когда я хочу создать отображение из кортежа в целое число. В Python я бы просто использовал кортеж (a,b) в качестве ключа к словарю,

Есть ли в Javascript кортежи? Я обнаружил, что (a,b) в javascript как выражение просто возвращает b (последний элемент). По-видимому, это унаследовано от C.

Итак, в качестве обходного пути я подумал, что вместо этого могу использовать массивы,

my_map[[a,b]] = c

Я попробовал это на консоли Firebug, и, похоже, это сработало. Это хороший способ сделать это?

Еще одна альтернатива, о которой я подумал, - создать строку из кортежей

my_map[""+a+":"+b] = c

Так что вопрос: есть ли проблемы с любым из этих методов? Есть ли лучший способ?

EDIT:

Небольшое уточнение: в моем случае a, b, c - целые числа

Ответы [ 4 ]

20 голосов
/ 15 сентября 2009

EcmaScript не различает индексацию свойства по имени или по [], например.

a.name

буквально эквивалентно

a["name"]

Единственное отличие состоит в том, что числа и т. Д. Не являются допустимым синтаксисом при доступе к именованному свойству

a.1
a.true

и т. Д. Имеют недопустимый синтаксис.

Увы, причина того, что все эти механизмы индексации одинаковы, заключается в том, что в EcmaScript все имена свойств являются строками. например.

a[1]

эффективно интерпретируется как

a[String(1)]

Что означает, что в вашем примере вы делаете:

my_map[[a,b]] = c

Что становится

my_map[String([a,b])] = c

По сути, это то же самое, что и ваш второй пример (однако, в зависимости от реализации, он может быть быстрее).

Если вы хотите поиск с истинным значением, вам нужно будет реализовать его самостоятельно на языке js, и вы потеряете доступ в стиле [:] (-

).
5 голосов
/ 15 сентября 2009

Вы можете использовать мою jshashtable , а затем использовать любой объект в качестве ключа, хотя при условии, что ваши кортежи являются массивами целых чисел Я думаю, что ваша лучшая ставка - та, которую вы упомянули сами: используйте метод join() Array для создания имен свойств обычного объекта. Вы можете обернуть это очень просто:

function TupleDictionary() {
 this.dict = {};
}

TupleDictionary.prototype = {
 tupleToString: function(tuple) {
  return tuple.join(",");
 },

 put: function(tuple, val) {
  this.dict[ this.tupleToString(tuple) ] = val;
 },

 get: function(tuple) {
  return this.dict[ this.tupleToString(tuple) ];
 }
};

var dict = new TupleDictionary();
dict.put( [1,2], "banana" );
alert( dict.get( [1,2] ) );
2 голосов
/ 15 сентября 2009

Все ключи объекта в Javascript являются строками. Использование my_map[[a,b]] = c приведет к ключу my_map, который будет результатом [a,b].toString(): a.toString() + ',' + b.toString(). На самом деле это может быть желательно (и похоже на использование a + ':' + b), но вы можете столкнуться с конфликтами, если ваши ключи содержат разделитель (или запятую, если вы используете массив в качестве ключа, или двоеточие, если вы пишете строка, как у вас в вашем примере).

Редактировать: альтернативным подходом было бы сохранить отдельный массив для ключевых ссылок. Например:

var keys = [
    [a,b],
    [c,d]
];
var my_map = {
    'keys[0]': /* Whatever [a,b] ought to be the key for */,
    'keys[1]': /* Whatever [c,d] ought to be the key for */
};
0 голосов
/ 05 февраля 2012

Самый простой и «естественный» способ добиться чего-то похожего - это использовать многомерные массивы, например:

var my_map = [["blah","blah","bla"],
              ["foo", "bla", 8],
              [324, 2345, 235],
              [true, false, "whatever..."]];
Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...