Bản đồ băm JavaScript được triển khai như thế nào?


88

Tôi hiện đang làm việc với OpenLayers và có một bộ dữ liệu khổng lồ để vẽ vào một lớp vectơ (lớn hơn 100000 vectơ).

Bây giờ tôi đang cố gắng đưa tất cả các vectơ này vào một bản đồ băm JavaScript để phân tích hiệu suất. Tôi muốn biết bản đồ băm trong JavaScript được triển khai như thế nào, nó là một hàm băm thực sự hay chỉ là một hàm được bọc sử dụng cấu trúc dữ liệu đơn giản và một thuật toán tìm kiếm?


2
Không chỉ có một triển khai JS, vì vậy không có cách nào để trả lời điều này. ECMAScript không chỉ định cấu trúc dữ liệu nào sẽ sử dụng cho các đối tượng, cũng như không chỉ định các hạn chế về thời gian truy cập. Cây băm là điển hình, nhưng có thể sử dụng cây cân bằng.
outis

1
ES6 có Bản đồ thuần túy. Các liên kết mô tả sự khác biệt giữa các đối tượng đồng bằng và Bản đồ, chi tiết quan trọng vv: MDN Javascript Bản đồ
Den La Mã

Câu trả lời:


193

mọi đối tượng javascript là một bản đồ băm đơn giản chấp nhận một chuỗi hoặc một Biểu tượng làm khóa của nó, vì vậy bạn có thể viết mã của mình dưới dạng:

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

Đối tượng javascript là một bản đồ băm thực khi triển khai nó, vì vậy độ phức tạp khi tìm kiếm là O (1), nhưng không có hashcode()chức năng dành riêng cho chuỗi javascript, nó được thực hiện bên trong bởi công cụ javascript (V8, SpiderMonkey, JScript.dll, v.v. .)

Cập nhật năm 2020:

javascript ngày nay cũng hỗ trợ các kiểu dữ liệu khác: MapWeakMap. Chúng hoạt động chặt chẽ hơn dưới dạng bản đồ băm hơn là các đối tượng truyền thống.


Hoàn hảo. Trước đây tôi đã sử dụng $ ('div # someDiv'). Data (key, value) và cái này đơn giản hơn nhiều và có lẽ cũng hỗ trợ tốt hơn cho các trình duyệt cũ. Cảm ơn
Swaroop

có cách nào để tìm chiều dài của bản đồ?
đá lăn vào

2
@Sridhar sử dụng Object.keys (bản đồ)
.length

1
Lưu ý: Bạn có thể sử dụng một số như một chìa khóa map[2] = 'foo'nhưng nó được đúc thành một chuỗi nội bộ> map = { '2': 'foo' }
Harry Moreno

@otakustay đó là tính năng tuyệt vời mà tôi biết đến hôm nay :) Thực sự tôi cần phải học Javascript chặt chẽ.
Pankaj Prakash

31

Các đối tượng JavaScript không thể được triển khai hoàn toàn trên các bản đồ băm.

Hãy thử điều này trong bảng điều khiển trình duyệt của bạn:

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

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

... và bạn sẽ nhận lại chúng theo thứ tự chèn, đó là tiêu chuẩn trên thực tế hành vi .

Bản đồ băm vốn dĩ không duy trì thứ tự, vì vậy việc triển khai JavaScript có thể sử dụng bản đồ băm bằng cách nào đó, nhưng nếu có, nó sẽ yêu cầu ít nhất một chỉ mục riêng và một số lưu trữ bổ sung để chèn.

Đây là video của Lars Bak giải thích lý do tại sao v8 không sử dụng bản đồ băm để triển khai các đối tượng .


3
"otakustay là sai về mặt kỹ thuật, loại sai tồi tệ nhất." Đó là một chút khắc nghiệt. Nó có thể không phải là 1: 1, nhưng đối với mục đích và mục đích của việc sử dụng hàm băm như từ điển, nó hoạt động theo cùng một kiểu.
có lẽ lên

1
Chỉ muốn làm rõ rằng điều này có thể đúng với một số triển khai JavaScript (chẳng hạn như hầu hết các trình duyệt) nhưng không nhất thiết luôn đúng. Thứ tự lặp qua các khóa không được xác định bởi tiêu chuẩn ECMAScript và có thể là bất kỳ thứ tự nào và vẫn là một triển khai JS hợp lệ.
TheZ

19

Đây là một cách dễ dàng và thuận tiện để sử dụng một thứ tương tự như bản đồ 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
    }

Và để nhận được giá trị:

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

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

12

Bạn có nên thử lớp học này không 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"

Lưu ý: khóa và giá trị có thể là bất kỳ loại nào.

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


4

Trong khi các đối tượng JavaScript cũ đơn giản có thể được sử dụng làm bản đồ, chúng thường được triển khai theo cách duy trì thứ tự chèn để tương thích với hầu hết các trình duyệt (xem câu trả lời của Craig Barnes) và do đó không phải là bản đồ băm đơn giản.

ES6 giới thiệu Bản đồ thích hợp (xem Bản đồ JavaScript MDN ) trong đó tiêu chuẩn cho biết :

Đối tượng bản đồ phải được triển khai bằng cách sử dụng bảng băm hoặc các cơ chế khác, trung bình, cung cấp thời gian truy cập theo tuyến con về số lượng phần tử trong tập hợp.


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

Tôi đã gặp sự cố trong đó tôi có json với một số khóa chung. Tôi muốn nhóm tất cả các giá trị có cùng một khóa. Sau khi lướt một số, tôi đã tìm thấy gói hashmap . Điều đó thực sự hữu ích.

Để nhóm phần tử có cùng một khóa, tôi đã sử dụng multi(key:*, value:*, key2:*, value2:*, ...).

Gói này tương tự như Java Hashmap collection, nhưng không mạnh bằng Java Hashmap.

Khi sử dụng trang web của chúng tôi, bạn xác nhận rằng bạn đã đọc và hiểu Chính sách cookieChính sách bảo mật của chúng tôi.
Licensed under cc by-sa 3.0 with attribution required.