2016-08-17 2 views
2

Я хотел бы хранить объекты, используя свои координаты, например, так:быстрый способ использования координат в качестве ключей в Javascript Hashmap

var hash_map = {}; 
hash_map[x + "-" + y] = new Object(); 

Они могут быть получены с помощью hash_map[x + "-" + y].

Однако я не уверен, что создание новой строки при каждом обращении к объекту - такая отличная идея.

В качестве альтернативы можно объединить координаты, делая что-то вроде x | (y >>> 16), но я понятия не имею о том, сколько бит сдвинуть значение y путем, что на самом деле происходит внутри (так как цифры JavaScript являются все поплавки, так что экспонента и мантисса и т. д.) и действительно ли это того стоит.

tl; dr Какой самый быстрый способ (включая сборку мусора) хранения объектов на карте хэша с координатами в качестве ключей?

+1

Часть того, что я могу ответить ... JavaScript битовые операторы все работают на 16-битных целых чисел –

+0

вы должны использовать хэш-карту? Предполагая, что координаты являются целыми числами, почему бы не использовать 2D-массив? Или даже 2D-хэш-карту. Если вы использовали массивы, вы можете предварительно выделить ключи и сэкономить на добавлении уникальных ключей каждый раз при обнаружении нового местоположения. –

+0

Каков максимальный размер координаты? Какой тип координаты (координаты GPS, координаты сетки и т. Д.)? – 10100111001

ответ

3

Вы можете использовать нижеследующее решение, чтобы собрать пару координат в одно 32-значное целое число со знаком. Это целое число можно затем использовать в качестве ключа для объекта JS. 2 координаты могут быть не более 16 бит. Поэтому x и y могут содержать только значения от -32767 до +32767 (2^15-1).

В приведенном ниже примере создается 100 случайных пар координат и добавляется к объекту hash_map с их значениями, содержащими координаты x и y, вычисленные из ключа. Координаты должны быть в пределах вышеупомянутого диапазона, иначе будет выбрано исключение.

var MAX_16BIT_SIGNED = 32767; //Math.floor((Math.pow(2, 16)/2)-1); 
 

 
function getRandomIntInclusive(min, max) { 
 
    min = Math.ceil(min); 
 
    max = Math.floor(max); 
 
    return Math.floor(Math.random() * (max - min + 1)) + min; 
 
} 
 

 
function getRandomKey() { 
 
    var x = getRandomIntInclusive(MAX_16BIT_SIGNED * -1, MAX_16BIT_SIGNED), 
 
    y = getRandomIntInclusive(MAX_16BIT_SIGNED * -1, MAX_16BIT_SIGNED); 
 

 
    //console.log("Generated key with x: " + x + " and y: " + y); 
 
    return getKey(x, y); 
 
} 
 

 
function getKey(x, y) { 
 
    if (x > MAX_16BIT_SIGNED || y > MAX_16BIT_SIGNED) 
 
    throw "Invalid X or Y value."; 
 
    x += MAX_16BIT_SIGNED; 
 
    y += MAX_16BIT_SIGNED; 
 
    return (x << 16) | y; 
 
} 
 

 
function getX(key) { 
 
    return (key >> 16) - MAX_16BIT_SIGNED; 
 
} 
 

 
function getY(key) { 
 
    return (key & 0xFFFF) - MAX_16BIT_SIGNED; 
 
} 
 

 
var hash_map = {}; 
 
hash_map[getKey(MAX_16BIT_SIGNED * -1, MAX_16BIT_SIGNED)] = "test"; 
 
hash_map[getKey(MAX_16BIT_SIGNED, MAX_16BIT_SIGNED)] = "test"; 
 
hash_map[getKey(MAX_16BIT_SIGNED * -1, MAX_16BIT_SIGNED * -1)] = "test"; 
 
hash_map[getKey(MAX_16BIT_SIGNED, MAX_16BIT_SIGNED * -1)] = "test"; 
 
//hash_map[getKey(MAX_16BIT_SIGNED+1, MAX_16BIT_SIGNED+1)] = "test"; 
 

 
for (var i = 0; i < 100; i++) { 
 
    var key = getRandomKey(); 
 
    hash_map[key] = { 
 
    x: getX(key), 
 
    y: getY(key) 
 
    }; 
 
} 
 
console.log(JSON.stringify(hash_map)); 
 
console.log(100 === Object.keys(hash_map).length);

Смежные вопросы