Javascript: usare le tuple come chiavi del dizionario
-
07-07-2019 - |
Domanda
Ho una situazione in cui voglio creare una mappatura da una tupla a un numero intero. In Python, userei semplicemente una tupla (a, b)
come chiave per un dizionario,
Javascript ha tuple? Ho scoperto che (a, b)
in javascript come espressione restituisce solo b (l'ultimo elemento). Apparentemente questo è ereditato da C.
Quindi, come soluzione alternativa, ho pensato di poter usare invece array,
my_map[[a,b]] = c
L'ho provato sulla console di Firebug e sembrava funzionare. È un buon modo per farlo?
Un'altra alternativa a cui ho pensato è quella di creare una stringa dalle tuple
my_map[""+a+":"+b] = c
Quindi la domanda è: c'è qualche problema con uno di questi metodi? C'è un modo migliore?
EDIT:
Piccolo chiarimento: nel mio caso, a, b, c sono tutti numeri interi
Soluzione
EcmaScript non distingue tra indicizzazione di una proprietà per nome o per []
, ad es.
a.name
è letteralmente equivalente a
a["name"]
L'unica differenza è che i numeri, ecc. non sono sintassi valida in un accesso alla proprietà con nome
a.1
a.true
e così via sono tutte sintassi non valide.
Purtroppo il motivo per cui tutti questi meccanismi di indicizzazione sono gli stessi è perché in EcmaScript i nomi delle proprietà tutti sono stringhe. ad es.
a[1]
viene effettivamente interpretato come
a[String(1)]
Il che significa che nel tuo esempio lo fai:
my_map[[a,b]] = c
Che diventa
my_map[String([a,b])] = c
Che è essenzialmente lo stesso di quello che sta facendo il tuo secondo esempio (tuttavia, a seconda dell'implementazione, potrebbe essere più veloce).
Se vuoi vere ricerche associative di valore dovrai implementarlo tu stesso in cima al linguaggio js, ??e perderai il piacevole accesso allo stile [] :-(
Altri suggerimenti
Puoi usare il mio jshashtable e quindi usare qualsiasi oggetto come chiave, anche se supponendo che le tue tuple siano matrici di numeri interi penso che la tua scommessa migliore sia quella che hai menzionato: usa il metodo join ()
di Array per creare nomi di proprietà di un oggetto normale. Potresti concludere questo molto semplicemente:
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] ) );
Tutte le chiavi dell'oggetto in Javascript sono stringhe. L'uso di my_map [[a, b]] = c
produrrà una chiave in my_map
che è il risultato di [a, b] .toString ()
: a.toString () + ',' + b.toString ()
. Questo può effettivamente essere desiderabile (ed è simile al tuo uso di a + ':' + b
), ma potresti riscontrare conflitti se le tue chiavi contengono il separatore (o la virgola se usi l'array come chiave o due punti se scrivi la stringa come nel tuo esempio).
Modifica: un approccio alternativo sarebbe quello di mantenere un array separato per i riferimenti chiave. Ad esempio:
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 */
};
il più semplice e "naturale" il modo per ottenere qualcosa di simile è utilizzare array multidimensionali, come questo:
var my_map = [["blah","blah","bla"],
["foo", "bla", 8],
[324, 2345, 235],
[true, false, "whatever..."]];