web-dev-qa-db-fra.com

Javascript: utiliser des tuples comme clés de dictionnaire

J'ai une situation où je veux créer un mappage d'un Tuple à un entier. En python, j'utiliserais simplement un Tuple (a,b) comme clé d'un dictionnaire,

Est-ce que Javascript a des tuples? J'ai trouvé que (a,b) en javascript en tant qu'expression ne fait que renvoyer b (le dernier élément). Apparemment, cela est hérité de C.

Donc, comme solution de contournement, je pensais pouvoir utiliser des tableaux à la place,

my_map[[a,b]] = c

Je l'ai essayé à la console Firebug et cela a semblé fonctionner. Est-ce une bonne façon de le faire?

Une autre alternative à laquelle j'ai pensé est de créer une chaîne à partir des tuples

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

La question est donc la suivante: y at-il un problème avec l’une de ces méthodes? Y a-t-il un meilleur moyen?

MODIFIER:

Petite précision: dans mon cas, a, b, c sont tous des entiers

28
hasen

EcmaScript ne fait pas la distinction entre l'indexation d'une propriété par son nom ou par [], par exemple.

a.name

est littéralement équivalent à

a["name"]

La seule différence est que les nombres, etc. ne sont pas une syntaxe valide dans un accès à une propriété nommée

a.1
a.true

et ainsi de suite sont toutes syntaxe non valide.

Hélas, la raison pour laquelle tous ces mécanismes d'indexation sont identiques est que, dans EcmaScript all , les noms de propriétés sont des chaînes. par exemple.

a[1]

est effectivement interprété comme

a[String(1)]

Ce qui signifie dans votre exemple que vous faites:

my_map[[a,b]] = c

Qui devient

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

Ce qui est essentiellement la même chose que ce que votre deuxième exemple est en train de faire (en fonction de la mise en œuvre, cela peut toutefois être plus rapide).

Si vous voulez de vraies recherches associatives, vous devrez l'implémenter vous-même en plus du langage js, et vous perdrez l'accès de style Nice [] :-(

20
olliej

Vous pouvez utiliser ma jshashtable et utiliser ensuite n'importe quel objet comme clé, bien que en supposant que vos n-uplets sont des tableaux d'entiers Je pense que votre meilleur pari est celui que vous avez mentionné: utilisez la méthode join() de Tableau pour créer des noms de propriétés d'un objet régulier. Vous pouvez envelopper ceci très simplement:

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] ) );
5
Tim Down

Toutes les clés d'objet en Javascript sont des chaînes. Utiliser my_map[[a,b]] = c produira une clé dans my_map qui est le résultat de [a,b].toString(): a.toString() + ',' + b.toString(). C’est peut-être souhaitable (et semblable à votre utilisation de a + ':' + b), mais vous pouvez rencontrer des conflits si vos clés contiennent le séparateur (soit la virgule si vous utilisez le tableau comme clé, soit les deux-points si vous écrivez la chaîne comme vous avez dans votre exemple).

Edit: Une autre approche serait de garder un tableau séparé pour les références clés. Par exemple:

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 */
};
2
eyelidlessness

le moyen le plus simple et "naturel" de réaliser quelque chose de similaire consiste à utiliser des tableaux multidimensionnels, comme ceci:

var my_map = [["blah","blah","bla"],
              ["foo", "bla", 8],
              [324, 2345, 235],
              [true, false, "whatever..."]];
0
Zelenova