Hướng dẫn ECMAScript Map Collection

Xem thêm các chuyên mục:

1- Collections - Map

ECMAScript 6 giới thiệu 2 cấu trúc trúc dữ liệu mới là Map & Set. Chúng là một phần trong nền tảng tập hợp (Collections Framework) của ECMAScript.
  • Maps - Cấu trúc dữ liệu này cho phép bạn lưu trữ các cặp "Khóa/Giá trị" (Key/Value). Và bạn có thể truy cập vào giá trị (value) thông qua khóa (key), hoặc cập nhập giá trị mới ứng với một khóa nào đó.
  • Sets - Cấu trúc dữ liệu này lưu trữ một danh sách các phần tử, không cho phép trùng lặp, và không đánh chỉ số cho các phần tử.
Trong bài viết này tôi sẽ giới thiệu với bạn về Map.
Xem thêm:

Map:

Một đối tượng Map lưu trữ các cặp "Khóa/Giá trị" (Key/Value). Trong đó Khóa và Giá trị có thể là các kiểu nguyên thủy (Primitive) hoặc các đối tượng (Object)
  • Trong đối tượng Map, các Khóa (Key) không được phép trùng lặp.
  • Map là một kiểu dữ liệu có thứ tự, điều đó có nghĩa là cặp "Khóa/Giá trị" nào được thêm vào trước sẽ đứng trước, cặp được thêm vào sau sẽ đứng sau.
Tạo một đối tượng Map thông qua constructor của lớp Map:
new Map( [iteratorObject] )
 
Các tham số:
  • iteratorObject - Là một đối tượng bất kỳ có thể lặp được (iterable).
Properties:
Property Mô tả
size Property này trả về số cặp "Khóa/Giá trị" của đối tượng Map.
map-size-example.js
var myContacts = new Map();

myContacts.set("0100-1111", "Tom");
myContacts.set("0100-5555", "Jerry");
myContacts.set("0100-2222", "Donald");

console.log(myContacts.size); // 3

for..of

Bạn có thể sử dụng vòng lặp for...of để lặp trên các cặp key/value của Map.
map-for-of-loop-example.js
// Create a Map object.
var myContacts = new Map();

myContacts.set("0100-1111", "Tom");
myContacts.set("0100-5555", "Jerry");
myContacts.set("0100-2222", "Donald");


for( let arr of myContacts)  {
  console.log(arr);
  console.log(" - Phone: " + arr[0]);
  console.log(" - Name: " + arr[1]);
}

2- Các phương thức của Map

set(key, value)

Phương thức set(key, newValue) sẽ thêm một cặp key/newValue vào đối tượng Map nếu không tồn tại cặp nào có khóa như vậy, ngược lại nó sẽ cập nhập giá trị mới cho cặp key/value tìm thấy trong Map.
map-set-example.js
var data = [
   ["0100-1111", "Tom"],
   ["0100-5555", "Jerry"],
   ["0100-2222", "Donald"]
];
var myContacts = new Map(data);

console.log(myContacts);

// Add new Key/Value pair to Map
myContacts.set("0100-9999", "Mickey");

console.log(myContacts);

// Update
myContacts.set("0100-5555", "Bugs Bunny");

console.log(myContacts);

has(key)

Phương thức này kiểm tra xem một khóa (key) có tồn tại trong Map hay không. Trả về true nếu tồn tại, ngược lại trả về false.
map-has-example.js
var data = [
   ["0100-1111", "Tom"],
   ["0100-5555", "Jerry"],
   ["0100-2222", "Donald"]
];
var myContacts = new Map(data);


var has = myContacts.has("0100-5555");

console.log("Has key 0100-5555? " + has); // true

clear()

Loại bỏ tất cả các cặp "Khóa/Giá trị" ra khỏi đối tượng Map.
map-clear-example.js
var data = [
   ["0100-1111", "Tom"],
   ["0100-5555", "Jerry"],
   ["0100-2222", "Donald"]
];
var myContacts = new Map(data);


console.log("Size: " + myContacts.size); // 3

myContacts.clear();

console.log("Size after clearing: " + myContacts.size); // 0

delete(key)

Xóa một cặp "Khóa/Giá trị" ra khỏi đối tượng Map, trả về true nếu một cặp bị loại bỏ ra khỏi Map, trả về false nếu Khóa (key) này không tồn tại trong Map.
map-delete-example.js
var data = [
   ["0100-1111", "Tom"],
   ["0100-5555", "Jerry"],
   ["0100-2222", "Donald"]
];
var myContacts = new Map(data);

console.log("Size: " + myContacts.size); // 3

var deleted = myContacts.delete("0100-5555");

console.log("Deleted? " + deleted); // true

console.log("Size after delete: " + myContacts.size); // 2
 

entries()

Trả về một đối tượng Iterator, mà mỗi entry (thực thể) của nó chứa một mảng 2 phần tử [key, value], thứ tự của các entry vẫn được giữ nguyên giống với thứ tự các cặp Key/Value trong đối tượng Map. (Xem hình minh họa dưới đây).
map-entries-example.js
var myContacts = new Map();

myContacts.set("0100-1111", "Tom");
myContacts.set("0100-5555", "Jerry");
myContacts.set("0100-2222", "Donald");

var entries = myContacts.entries();

var entry;

while( !(entry = entries.next()).done )  {
  var array = entry.value;

  console.log(array); // [ '0100-1111', 'Tom' ]
}

keys()

Phương thức này trả về một đối tượng Iterator mới giúp bạn truy cập vào các khóa (key) của đối tượng Map.
map-keys-example.js
var data = [
   ["0100-1111", "Tom"],
   ["0100-5555", "Jerry"],
   ["0100-2222", "Donald"]
];
var myContacts = new Map(data);

var iteratorPhones= myContacts.keys();

var entry;

while( !(entry = iteratorPhones.next()).done )  {
  var phone = entry.value;

  console.log(phone); // 0100-1111
}

values()

Phương thức này trả về một đối tượng Iterator mới giúp bạn truy cập vào các giá trị (value) của đối tượng Map.
map-values-example.js
var data = [
   ["0100-1111", "Tom"],
   ["0100-5555", "Jerry"],
   ["0100-2222", "Donald"]
];
var myContacts = new Map(data);

var iteratorNames = myContacts.values();

var entry;

while( !(entry = iteratorNames.next()).done )  {
  var name = entry.value;

  console.log(name); // Tom
}

forEach(callbackFn [, thisArg])

Phương thức này sẽ gọi hàm callbackFn một lần ứng với mỗi cặp "Khóa/Giá trị" của đối tượng Map.
myMap.forEach(callback[, thisArg])
 
Các tham số:
  • callbackFn - Hàm này sẽ được gọi một lần ứng với mỗi cặp "Khóa/Giá trị" của đối tượng Map.
  • thisArg - Tham số được sử dụng như this khi thực thi hàm callbackFn.
map-forEach-example.js
var showContact = function(key, value, thisMap)  {
    console.log("Phone: " + key +". Name: " + value);
}

var data = [
   ["0100-1111", "Tom"],
   ["0100-5555", "Jerry"],
   ["0100-2222", "Donald"]
];
var myContacts = new Map(data);

// or call: myContacts.forEach(showContact)
myContacts.forEach(showContact, myContacts);

3- WeakMap

Về cơ bản WeakMap khá giống với Map, nhưng nó có các khác biệt sau:
  1. Các khóa (Key) của nó phải là các đối tượng (Object)
  2. Các khóa của WeakMap có thể bị loại bỏ trong tiến trình (process) thu gom rác (Garbage collection), đây là một tiến trình (process) độc lập để loại bỏ các đối tượng không còn được sử dụng trong chương trình.
  3. WeakMap không hỗ trợ property: size, vì vậy bạn không thể biết nó có bao nhiêu phần tử.
  4. Có nhiều phương thức được có trong lớp Map nhưng không có lớp WeakMap, chẳng hạn values(), keys(), entries(), clear(),..
Chú ý: Bạn không thể sử dụng vòng lặp for..of đối với WeakMap, và cũng không có cách nào để bạn lặp (iterate) trên các cặp key/value của WeakMap.
Tạo một đối tượng WeakMap.
var map2 = new WeakMap( [iteratorObject] )
Các tham số:
  • iteratorObject - Là một đối tượng bất kỳ có thể lặp được (iterable).

Methods:

Số lượng các phương thức của WeakMap ít hơn so với số lượng các phương thức của Map:
  1. WeakMap.delete(key)
  2. WeakMap.get(key)
  3. WeakMap.has(key)
  4. WeakMap.set(key, value)
Các khóa (key) trong WeakMap phải là một đối tượng, nó không thể là một kiểu nguyên thủy ( Primitive).
let w = new WeakMap();
w.set('a', 'b'); // Uncaught TypeError: Invalid value used as weak map key

let m = new Map();
m.set('a', 'b'); // Works
weakmap-example.js
var key1 = {}; // An Object
var key2 = {foo: "bar"};
var key3 = {bar: "foo"};

var data = [
   [key1, "Tom"],
   [key2, "Jerry"],
   [key3, "Donald"]
];
var myWeakMap = new WeakMap(data);

console.log(myWeakMap.get(key1));

Xem thêm các chuyên mục: