Hướng dẫn create hashmap in javascript - tạo hashmap trong javascript

Map là một trong những cấu trúc dữ liệu được sử dụng thường xuyên nhất trong lập trình. Nó giữ các cặp khóa - giá trị có thể dễ dàng truy cập bằng các khóa của chúng. Trong JavaScript, chúng ta có thể tạo ra một map một cách đơn giản bằng cách sử dụng một object {}. Ví dụ:

const map = {}; // insert key-value-pair map['key1'] = 'value1'; map['key2'] = 'value2'; map['key3'] = 'value3'; // check if map contians key if (map['key1']) { console.log('Map contains key1'); } // get value with specific key console.log(map['key1']);

Khá là đơn giản đúng không? Chính vì nó đơn giản nên chúng ta sử dụng nó thường xuyên mà quên đi kiểu dữ liệu mà JavaScript đã tạo sẵn cho chúng ta Map.

Ơ cơ mà, const map = new Map(); const myFunction = () => console.log('I am a useful function.'); const myNumber = 666; const myObject = { name: 'plainObjectValue', otherKey: 'otherValue' }; map.set(myFunction, 'function as a key'); map.set(myNumber, 'number as a key'); map.set(myObject, 'object as a key'); console.log(map.get(myFunction)); // function as a key console.log(map.get(myNumber)); // number as a key console.log(map.get(myObject)); // object as a key 0 đơn giản, dễ dùng hơn? tại sao lại phải dùng Map

1. Key types

Đối với một object, const map = new Map(); const myFunction = () => console.log('I am a useful function.'); const myNumber = 666; const myObject = { name: 'plainObjectValue', otherKey: 'otherValue' }; map.set(myFunction, 'function as a key'); map.set(myNumber, 'number as a key'); map.set(myObject, 'object as a key'); console.log(map.get(myFunction)); // function as a key console.log(map.get(myNumber)); // number as a key console.log(map.get(myObject)); // object as a key 2 bị giới hạn trong chuỗi hoặc số. Còn với Map, chúng ta có nhiều lựa chọn hơn như object, function hay các giá trị nguyên thủy

const map = new Map(); const myFunction = () => console.log('I am a useful function.'); const myNumber = 666; const myObject = { name: 'plainObjectValue', otherKey: 'otherValue' }; map.set(myFunction, 'function as a key'); map.set(myNumber, 'number as a key'); map.set(myObject, 'object as a key'); console.log(map.get(myFunction)); // function as a key console.log(map.get(myNumber)); // number as a key console.log(map.get(myObject)); // object as a key

2. Better Size Determination

Với một map dạng const map = new Map(); const myFunction = () => console.log('I am a useful function.'); const myNumber = 666; const myObject = { name: 'plainObjectValue', otherKey: 'otherValue' }; map.set(myFunction, 'function as a key'); map.set(myNumber, 'number as a key'); map.set(myObject, 'object as a key'); console.log(map.get(myFunction)); // function as a key console.log(map.get(myNumber)); // number as a key console.log(map.get(myObject)); // object as a key 0. Cách chúng ta thường dùng để xác định kích thước của nó là tính size của const map = new Map(); const myFunction = () => console.log('I am a useful function.'); const myNumber = 666; const myObject = { name: 'plainObjectValue', otherKey: 'otherValue' }; map.set(myFunction, 'function as a key'); map.set(myNumber, 'number as a key'); map.set(myObject, 'object as a key'); console.log(map.get(myFunction)); // function as a key console.log(map.get(myNumber)); // number as a key console.log(map.get(myObject)); // object as a key 5 hoặcconst map = new Map(); const myFunction = () => console.log('I am a useful function.'); const myNumber = 666; const myObject = { name: 'plainObjectValue', otherKey: 'otherValue' }; map.set(myFunction, 'function as a key'); map.set(myNumber, 'number as a key'); map.set(myObject, 'object as a key'); console.log(map.get(myFunction)); // function as a key console.log(map.get(myNumber)); // number as a key console.log(map.get(myObject)); // object as a key 6 của object đó. Còn đối với Map, chúng ta chỉ cần dùng hàm const map = new Map(); const myFunction = () => console.log('I am a useful function.'); const myNumber = 666; const myObject = { name: 'plainObjectValue', otherKey: 'otherValue' }; map.set(myFunction, 'function as a key'); map.set(myNumber, 'number as a key'); map.set(myObject, 'object as a key'); console.log(map.get(myFunction)); // function as a key console.log(map.get(myNumber)); // number as a key console.log(map.get(myObject)); // object as a key 8 là xong.

Đối với Map, độ phức tạp để xác định size của nó const map = new Map(); map.set('someKey1', 1); map.set('someKey2', 1); ... map.set('someKey100', 1); console.log(map.size) // 100, Runtime: O(1) const plainObjMap = {}; plainObjMap['someKey1'] = 1; plainObjMap['someKey2'] = 1; ... plainObjMap['someKey100'] = 1; console.log(Object.keys(plainObjMap).length) // 100, Runtime: O(n) 0 là const map = new Map(); map.set('someKey1', 1); map.set('someKey2', 1); ... map.set('someKey100', 1); console.log(map.size) // 100, Runtime: O(1) const plainObjMap = {}; plainObjMap['someKey1'] = 1; plainObjMap['someKey2'] = 1; ... plainObjMap['someKey100'] = 1; console.log(Object.keys(plainObjMap).length) // 100, Runtime: O(n) 1, còn với object thì luôn là const map = new Map(); map.set('someKey1', 1); map.set('someKey2', 1); ... map.set('someKey100', 1); console.log(map.size) // 100, Runtime: O(1) const plainObjMap = {}; plainObjMap['someKey1'] = 1; plainObjMap['someKey2'] = 1; ... plainObjMap['someKey100'] = 1; console.log(Object.keys(plainObjMap).length) // 100, Runtime: O(n) 2

const map = new Map(); map.set('someKey1', 1); map.set('someKey2', 1); ... map.set('someKey100', 1); console.log(map.size) // 100, Runtime: O(1) const plainObjMap = {}; plainObjMap['someKey1'] = 1; plainObjMap['someKey2'] = 1; ... plainObjMap['someKey100'] = 1; console.log(Object.keys(plainObjMap).length) // 100, Runtime: O(n)

3. Better Performance

Map được tối ưu hóa để thường xuyên thêm / xóa các phần tử. Vậy nên hiển nhiên nó sẽ có hiệu năng tốt hơn object. Tuy nhiên, khi dữ liệu chưa đủ nhiều thì object sẽ cho hiệu năng tốt hơn

4. Direct Iteration

Cách mà chúng ta thường dùng để duyệt 1 map dạng object là duyệt theo const map = new Map(); const myFunction = () => console.log('I am a useful function.'); const myNumber = 666; const myObject = { name: 'plainObjectValue', otherKey: 'otherValue' }; map.set(myFunction, 'function as a key'); map.set(myNumber, 'number as a key'); map.set(myObject, 'object as a key'); console.log(map.get(myFunction)); // function as a key console.log(map.get(myNumber)); // number as a key console.log(map.get(myObject)); // object as a key 5 của object đó. Còn đối với Map, chúng ta có thể duyệt const map = new Map(); map.set('someKey1', 1); map.set('someKey2', 1); ... map.set('someKey100', 1); console.log(map.size) // 100, Runtime: O(1) const plainObjMap = {}; plainObjMap['someKey1'] = 1; plainObjMap['someKey2'] = 1; ... plainObjMap['someKey100'] = 1; console.log(Object.keys(plainObjMap).length) // 100, Runtime: O(n) 6

const map = new Map(); map.set('someKey1', 1); map.set('someKey2', 2); map.set('someKey3', 3); for (let [key, value] of map) { console.log(`${key} = ${value}`); } // someKey1 = 1 // someKey2 = 2 // someKey3 = 3 const plainObjMap = {}; plainObjMap['someKey1'] = 1; plainObjMap['someKey2'] = 2; plainObjMap['someKey3'] = 3; for (let key of Object.keys(plainObjMap)) { const value = plainObjMap[key]; console.log(`${key} = ${value}`); } // someKey1 = 1 // someKey2 = 2 // someKey3 = 3

5. Key Order

Trước phiên bản const map = new Map(); map.set('someKey1', 1); map.set('someKey2', 1); ... map.set('someKey100', 1); console.log(map.size) // 100, Runtime: O(1) const plainObjMap = {}; plainObjMap['someKey1'] = 1; plainObjMap['someKey2'] = 1; ... plainObjMap['someKey100'] = 1; console.log(Object.keys(plainObjMap).length) // 100, Runtime: O(n) 7, const map = new Map(); const myFunction = () => console.log('I am a useful function.'); const myNumber = 666; const myObject = { name: 'plainObjectValue', otherKey: 'otherValue' }; map.set(myFunction, 'function as a key'); map.set(myNumber, 'number as a key'); map.set(myObject, 'object as a key'); console.log(map.get(myFunction)); // function as a key console.log(map.get(myNumber)); // number as a key console.log(map.get(myObject)); // object as a key 5 của mỗi object không được đảm bảo theo bất kỳ thứ tự cụ thể nào. Bạn có thể thêm 1 phần tử ở vị trí 10 trong khi vị trí 9 chưa có phần tử nào. Còn đối với Map, thứ tự của các phần tử được xác định đúng theo thứ tự mà nó được thêm vào Map.

6. No Key Overriding

Một object mặc định sẽ có một vài const map = new Map(); const myFunction = () => console.log('I am a useful function.'); const myNumber = 666; const myObject = { name: 'plainObjectValue', otherKey: 'otherValue' }; map.set(myFunction, 'function as a key'); map.set(myNumber, 'number as a key'); map.set(myObject, 'object as a key'); console.log(map.get(myFunction)); // function as a key console.log(map.get(myNumber)); // number as a key console.log(map.get(myObject)); // object as a key 5 theo const map = new Map(); map.set('someKey1', 1); map.set('someKey2', 2); map.set('someKey3', 3); for (let [key, value] of map) { console.log(`${key} = ${value}`); } // someKey1 = 1 // someKey2 = 2 // someKey3 = 3 const plainObjMap = {}; plainObjMap['someKey1'] = 1; plainObjMap['someKey2'] = 2; plainObjMap['someKey3'] = 3; for (let key of Object.keys(plainObjMap)) { const value = plainObjMap[key]; console.log(`${key} = ${value}`); } // someKey1 = 1 // someKey2 = 2 // someKey3 = 3 2 của nó. Vậy nên có thể xảy ra xung đột giữa const map = new Map(); const myFunction = () => console.log('I am a useful function.'); const myNumber = 666; const myObject = { name: 'plainObjectValue', otherKey: 'otherValue' }; map.set(myFunction, 'function as a key'); map.set(myNumber, 'number as a key'); map.set(myObject, 'object as a key'); console.log(map.get(myFunction)); // function as a key console.log(map.get(myNumber)); // number as a key console.log(map.get(myObject)); // object as a key 5 đã có sẵn trong object với key của bạn (xem tại ví dụ phía dưới) Đối với Map, nó không có một const map = new Map(); const myFunction = () => console.log('I am a useful function.'); const myNumber = 666; const myObject = { name: 'plainObjectValue', otherKey: 'otherValue' }; map.set(myFunction, 'function as a key'); map.set(myNumber, 'number as a key'); map.set(myObject, 'object as a key'); console.log(map.get(myFunction)); // function as a key console.log(map.get(myNumber)); // number as a key console.log(map.get(myObject)); // object as a key 5 mặc định nào cả nên sẽ không xảy ra trường hợp này

const map = new Map(); map.set('someKey1', 1); map.set('someKey2', 2); map.set('toString', 3); // No problem for Map const plainObjMap = new Map(); plainObjMap['someKey1'] = 1; plainObjMap['someKey2'] = 2; plainObjMap['toString'] = 3; // Oops, native property

Nguồn: //medium.com/better-programming/stop-using-objects-as-hash-maps-in-javascript-9a272e85f6a8

Chủ đề