Як реалізується хеш-карта JavaScript?


88

На даний момент я працюю з OpenLayers і маю величезний набір даних для введення у векторний шар (більше 100000 векторів).

Зараз я намагаюся помістити всі ці вектори в хеш-карту JavaScript для аналізу продуктивності. Я хочу знати, як реалізована хеш-карта в JavaScript, це справжня хеш-функція чи просто загорнута функція, яка використовує просту структуру даних та алгоритм пошуку?


2
Існує не тільки одна реалізація JS, тому немає можливості відповісти на це. ECMAScript не визначає, яку структуру даних використовувати для об'єктів, а також не визначає обмеження часу доступу. Хаші є типовими, але можна використовувати збалансовані дерева.
outis

1
ES6 мають чисті Карти. Посилання описує відмінності між звичайним об’єктом та картою, ключовими деталями тощо: MDN JavaScript Map
Den Roman

Відповіді:


193

кожен об'єкт javascript - це проста хеш-карта, яка приймає рядок або символ як свій ключ, тому ви можете написати свій код як:

var map = {};
// add a item
map[key1] = value1;
// or remove it
delete map[key1];
// or determine whether a key exists
key1 in map;

Об'єкт javascript є справжньою хеш-картою для його реалізації, тому складність пошуку становить O (1), але hashcode()для рядків javascript немає виділеної функції, він реалізований внутрішньо за допомогою механізму javascript (V8, SpiderMonkey, JScript.dll тощо). .)

Оновлення 2020 року:

javascript сьогодні підтримує також інші типи даних: Mapі WeakMap. Вони поводяться більше як хеш-карти, ніж традиційні об'єкти.


Ідеально Я раніше використовував дані $ ('div # someDiv'). Data (ключ, значення), і цей набагато простіший, і, мабуть, також має кращу підтримку для старих браузерів. Дякую
Swaroop

чи є спосіб знайти довжину карти?
камінчик

2
@Sridhar use Object.keys (map) .length
отакустай

1
Зверніть увагу, що ви можете використовувати число як ключ, map[2] = 'foo'але воно всередині > map = { '2': 'foo' }
Гаррі Морено

@otakustay, це була надзвичайно крута функція, яку я сьогодні дізнався :) Дійсно, мені потрібно уважно вивчити Javascript.
Панкадж Пракаш

31

Об'єкти JavaScript не можуть бути реалізовані лише поверх хеш-карт.

Спробуйте це на консолі браузера:

var foo = {
    a: true,
    b: true,
    z: true,
    c: true
}

for (var i in foo) {
    console.log(i);
}

... і ви отримаєте їх назад у порядку вставки, що є де-факто стандартною поведінкою.

Карти хешів за своєю суттю не підтримують упорядкування, тому реалізації JavaScript можуть якось використовувати хеш-карти, але якщо вони це роблять, для вставки потрібно буде принаймні окремий індекс та додаткове ведення книги.

Ось відео Ларса Бека, який пояснює, чому v8 не використовує хеш-карти для реалізації об’єктів .


3
"отакустай є технічно неправильним, найгіршим видом помилки". Це трохи жорстко. Це може бути не 1: 1, але для намірів і цілей використання хешу, як словник, він працює однаково.
ймовірнодо

1
Просто хочу пояснити, що це може бути правдою для деяких реалізацій JavaScript (таких як більшість браузерів), але не обов'язково завжди правдою. Порядок ітерацій за ключами не визначений стандартами ECMAScript і може бути будь-яким порядком і все ще бути чинною реалізацією JS.
TheZ

19

Ось простий і зручний спосіб використання чогось подібного до карти Java :

var map= {
    'map_name_1': map_value_1,
    'map_name_2': map_value_2,
    'map_name_3': map_value_3,
    'map_name_4': map_value_4
    }

І щоб отримати значення:

alert( map['map_name_1'] );    // fives the value of map_value_1

......  etc  .....

13

Якщо ви спробуєте цей клас Map:

var myMap = new Map();

// setting the values
myMap.set("1", 'value1');
myMap.set("2", 'value2');
myMap.set("3", 'value3');

myMap.size; // 3

// getting the values
myMap.get("1");    // "value associated with "value1"
myMap.get("2");       // "value associated with "value1"
myMap.get("3");      // "value associated with "value3"

Примітка: ключ і значення можуть бути будь-якого типу.

https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Map


4

Хоча звичайні старі об'єкти JavaScript можна використовувати як карти, вони, як правило, реалізовані таким чином, щоб зберегти порядок вставки для сумісності з більшістю браузерів (див. Відповідь Крейга Барнса) і, отже, не є простими хеш-картами.

ES6 представляє належні Карти (див. MDN JavaScript Map ), про які стандарт говорить :

Об'єкт карти повинен бути реалізований за допомогою хеш-таблиць або інших механізмів, які в середньому забезпечують час доступу, який є підлінійним за кількістю елементів у колекції.


1
<html>
<head>
<script type="text/javascript">
function test(){
var map= {'m1': 12,'m2': 13,'m3': 14,'m4': 15}
     alert(map['m3']);
}
</script>
</head>
<body>
<input type="button" value="click" onclick="test()"/>
</body>
</html>

0

Я стикався з проблемою, коли у мене був json з деякими загальними ключами. Я хотів згрупувати всі значення, що мають однаковий ключ. Після серфінгу я знайшов пакет hashmap . Що справді корисно.

Для групування елемента за тим самим ключем я використовував multi(key:*, value:*, key2:*, value2:*, ...).

Цей пакет дещо схожий на колекцію Java Hashmap, але не такий потужний, як Java Hashmap.

Використовуючи наш веб-сайт, ви визнаєте, що прочитали та зрозуміли наші Політику щодо файлів cookie та Політику конфіденційності.
Licensed under cc by-sa 3.0 with attribution required.