skip to Main Content

Javascript Map()s compare object keys by identity, which means Map<[number, number], any> is a bad idea:

const map = new Map();
const coordinates = [1, 3];

map.set(coordinates, 0);
map.get([1, 3]);
# undefined

To avoid this, we commonly see keys set as `${a}_${b}`. That’s reasonably fast, but it involves number-to-string conversion. If we know the range of A and B, we could do (a << 8) + b which is 2-3x faster in my testing: http://jsben.ch/JRG9z

For integers with unknown domain, is there a similar approach to the bitshift the uniqueness of the resulting key, but doesn’t involve a string cast?

2

Answers


  1. I usually use a nested object for this. Could be replaced with map also (more coding):

    class CoordMap{
      map = {};
      set(coord, val){
        (this.map[coord[0]] ??= {})[coord[1]] = val;
      }
      get(coord){
        return this.map[coord[0]]?.[coord[1]];
      }
    }
    
    const map = new CoordMap;
    const coordinates = [1, 3];
    
    map.set(coordinates, 0);
    console.log(map.get([1, 3]));
    Login or Signup to reply.
  2. For integers with unknown domain, is there a similar approach to the bitshift the uniqueness of the resulting key, but doesn’t involve a string cast?

    No. Integers with an unknown domain carry at least 53 bits of information, so there’s no way to fit two integers into a single JS number (max 64 bits of information) without collisions.

    Login or Signup to reply.
Please signup or login to give your own answer.
Back To Top
Search