TransWikia.com

Javascript: using tuples as dictionary keys

Stack Overflow Asked by hasen on November 12, 2021

I have a situation where I want to create a mapping from a tuple to an integer. In python, I would simply use a tuple (a,b) as the key to a dictionary,

Does Javascript have tuples? I found that (a,b) in javascript as an expression just returns b (the last item). Apparently this is inherited from C.

So, as a workaround, I thought I can use arrays instead,

my_map[[a,b]] = c

I tried it at the Firebug console and it seemed to work. Is that a good way to do it?

Another alternative I thought of is to create a string out of the tuples

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

So the question is: is there any problem with any of these methods? Is there a better way?

EDIT:

Small clarification: in my case, a,b,c are all integers

4 Answers

the most simple and "natural" way to achieve something similar is by using multidimensional arrays, like this:

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

Answered by Zelenova on November 12, 2021

You could use my jshashtable and then use any object as a key, though assuming your tuples are arrays of integers I think your best bet is one you've mentioned yourself: use the join() method of Array to create property names of a regular object. You could wrap this very simply:

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] ) );

Answered by Tim Down on November 12, 2021

All object keys in Javascript are strings. Using my_map[[a,b]] = c will produce a key in my_map which is the result of [a,b].toString(): a.toString() + ',' + b.toString(). This may actually be desirable (and is similar to your use of a + ':' + b), but you may run into conflicts if your keys contain the separator (either the comma if you use the array as the key, or the colon if you write the string as you have in your example).

Edit: An alternate approach would be to keep a separate array for key references. Eg:

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

Answered by eyelidlessness on November 12, 2021

EcmaScript doesn't distinguish between indexing a property by name or by [], eg.

a.name

is literally equivalent to

a["name"]

The only difference is that numbers, etc are not valid syntax in a named property access

a.1
a.true

and so on are all invalid syntax.

Alas the reason all of these indexing mechanisms are the same is because in EcmaScript all property names are strings. eg.

a[1]

is effectively interpreted as

a[String(1)]

Which means in your example you do:

my_map[[a,b]] = c

Which becomes

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

Which is essentially the same as what your second example is doing (depending on implementation it may be faster however).

If you want true value-associative lookups you will need to implement it yourself on top of the js language, and you'll lose the nice [] style access :-(

Answered by olliej on November 12, 2021

Add your own answers!

Ask a Question

Get help from others!

© 2024 TransWikia.com. All rights reserved. Sites we Love: PCI Database, UKBizDB, Menu Kuliner, Sharing RPP