Javascript: использование кортежей в качестве словарных ключей

StackOverflow https://stackoverflow.com/questions/1425186

  •  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..."]];
Лицензировано под: CC-BY-SA с атрибуция
Не связан с StackOverflow
scroll top