JavaScriptハッシュマップはどのように実装されていますか?


88

私は現在OpenLayersを使用しており、ベクターレイヤー(100000を超えるベクター)に描画するための膨大なデータセットを持っています。

現在、これらすべてのベクトルをJavaScriptハッシュマップに入れて、パフォーマンスを分析しようとしています。JavaScriptのハッシュマップがどのように実装されているのか知りたいのですが、それは実際のハッシュ関数ですか、それとも単純なデータ構造と検索アルゴリズムを使用するラップされた関数ですか?


2
JSの実装は1つだけではないため、これに答える方法はありません。ECMAScriptは、オブジェクトに使用するデータ構造を指定せず、アクセス時間の制限も指定しません。ハッシュが一般的ですが、バランスの取れたツリーを使用できます。
outis 2012年

1
ES6には純粋なマップがあります。リンクには、プレーンオブジェクトとマップの違い、重要な詳細などが記載されています。MDNJavaScriptマップ
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は、他のデータ型もサポートしています:MapWeakMap。これらは、従来のオブジェクトよりもハッシュマップとしてより密接に動作します。


完璧です。以前は$( 'div#someDiv')。data(key、value)を使用していましたが、これははるかに単純で、おそらく古いブラウザーのサポートも優れています。ありがとう
Swaroop 2013年

マップの長さを見つける方法はありますか?
ローリングストーン

2
@Sridhar use Object.keys(map).length
otakustay 2015年

1
数字をキーとして使用できますが、map[2] = 'foo'内部的に文字列にキャストされることに注意してください> map = { '2': 'foo' }
Harry Moreno

@otakustayは、今日私が知った非常にクールな機能でした:)本当にJavascriptを綿密に学ぶ必要があります。
Pankaj Prakash 2018

31

JavaScriptオブジェクトは、ハッシュマップの上に純粋に実装することはできません。

ブラウザコンソールでこれを試してください。

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

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

...そして、挿入順にそれらを受け取ります。これは事実上の標準的な動作です。

ハッシュマップは本質的に順序を維持しないため、JavaScript実装は何らかの方法でハッシュマップを使用する場合がありますが、そうする場合は、少なくとも個別のインデックスと挿入用の追加の簿記が必要になります。

これは、v8がオブジェクトの実装にハッシュマップを使用しない理由を説明するLarsBakのビデオです


3
「オタクステイは技術的に間違っており、最悪の種類の間違いです。」それは少し厳しいです。1:1ではないかもしれませんが、辞書のようなハッシュを使用する意図と目的のために、同じように機能します。
おそらく

1
これはJavaScriptの一部の実装(ほとんどのブラウザーなど)に当てはまる可能性があることを明確にしたいだけですが、必ずしも当てはまるとは限りません。キーに対する反復の順序はECMAScript標準で定義されておらず、任意の順序であり、有効なJS実装である可能性があります。
TheZ 2015年

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  .....

12

このクラスを試してみてください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オブジェクトはマップとして使用できますが、通常、ほとんどのブラウザーとの互換性のために挿入順序を維持する方法で実装されているため(Craig Barnesの回答を参照)、単純なハッシュマップではありません。

ES6は(参照適切な地図を紹介しMDN JavaScriptの地図をそのうち)標準は言います

マップオブジェクトは、ハッシュテーブルまたは他のメカニズムを使用して実装する必要があります。これらのメカニズムは、平均して、コレクション内の要素の数に対して劣線形のアクセス時間を提供します。


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を持っているという問題に遭遇していました。同じキーを持つすべての値をグループ化したかったのです。サーフィンをした後、ハッシュマップパッケージを見つけました。これは本当に役に立ちます。

同じキーで要素をグループ化するために、を使用しましたmulti(key:*, value:*, key2:*, value2:*, ...)

このパッケージはJavaHashmapコレクションにいくぶん似ていますが、JavaHashmapほど強力ではありません。

弊社のサイトを使用することにより、あなたは弊社のクッキーポリシーおよびプライバシーポリシーを読み、理解したものとみなされます。
Licensed under cc by-sa 3.0 with attribution required.