Javascript: использование кортежей в качестве словарных ключей
-
07-07-2019 - |
Вопрос
У меня есть ситуация, когда я хочу создать отображение из кортежа в целое число. В Python я бы просто использовал кортеж (a, b)
в качестве ключа к словарю,
Есть ли в Javascript кортежи? Я обнаружил, что (a, b)
в javascript как выражение просто возвращает b (последний элемент). По-видимому, это унаследовано от C.
Итак, в качестве обходного пути я подумал, что вместо этого я могу использовать массивы,
my_map[[a,b]] = c
Я попробовал это на консоли Firebug, и это, похоже, сработало. Это хороший способ сделать это?
Еще одна альтернатива, о которой я подумал, - создать строку из кортежей
my_map[""+a+":"+b] = c
Итак, вопрос: есть ли проблема с любым из этих методов? Есть ли лучший способ?
EDIT:
Небольшое уточнение: в моем случае a, b, c - целые числа
Решение
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, и вы потеряете доступ в стиле []: - (
Другие советы
Вы можете использовать мой jshashtable , а затем использовать любой объект в качестве ключа, хотя предполагая, что ваши кортежи - это массивы целых чисел . Я думаю, что ваша лучшая ставка - та, о которой вы упомянули сами: используйте метод Array join ()
для создания имен свойств обычного объекта. Вы можете обернуть это очень просто:
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] ) );
Все ключи объекта в 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 */
};
самый простой и "естественный" Чтобы добиться чего-то похожего, используйте многомерные массивы, например:
var my_map = [["blah","blah","bla"],
["foo", "bla", 8],
[324, 2345, 235],
[true, false, "whatever..."]];