JavaScript Map and Set
Map và Set là hai loại cấu trúc dữ liệu trong JavaScript mà bạn có thể sử dụng để lưu trữ một tập hợp các giá trị tương tự như Object hay Array. Đây là những cấu trúc dữ liệu chuyên biệt có thể giúp bạn lưu trữ và thao tác với các giá trị liên quan.
Trong bài viết này chúng ta sẽ tìm hiểu chi tiết về cách hoạt động của Map
và Set
, khi nào nên sử dụng chúng. Chúng ta cũng sẽ khám phá các phương thức của đối tượng Map
Set
mới được thêm vào JavaScript gần đây.
1. Map Object
Đối tượng Map
lưu trữ dữ liệu theo cấu trúc key/value giống với Object. Điểm khác biệt chính:
Map
có thể dùng bất kì kiểu dữ liệu nào để làm keyMap
duy trì thứ tự của dữ liệu mới được thêm vào
1-1. How to Create
Để khởi tạo một đối tượng Map
ta sử dụng hàm khởi tạo (constructor) như sau:
const myMap = new Map();
1-2. Methods and Properties
Đối tượng Map
có các phương thức và thuộc tính sau:
set(key, value)
– Thêm một phần tử mới với key/value cụ thể vàoMap
. Nếu phần tử đó trùng với key đã tồn tại, nó sẽ được cập nhật với giá trị mới.get(key)
– Trả về giá trị value của key đó (returnsundefined
if key doesn't exist)has(key)
– Check xem Map có key đó hay khôngdelete(key)
– Xóa một key cụ thểclear()
– Xóa tất cả các phần tử khỏi Mapkeys()
– Trả về tất cả các keys trong Mapvalues()
– Trả về tất cả các values trong Mapentries()
– Trả về tất cả các cặp key/value trong Mapsize
– Trả về số lượng các phần tử trong Map
Để insert data vào trong Map
, chúng ta sử dụng phương thức set()
:
const myMap = new Map();
myMap.set(1, 'Jack');
myMap.set(2, 'Jill');
myMap.set('animal', 'Elephant');
Đoạn code trên tạo ra một đối tượng Map
như sau:
Map(3)
0: {1 => "Jack"}
1: {2 => "Jill"}
2: {"animal" => "Elephant"}
Để get value từ đối tượng Map
bạn có thể sử dụng phương thức get()
và truyền key vào làm đối số:
console.log(myMap.get(1)); // Jack
console.log(myMap.get('animal')); // Elephant
Để kiểm tra xem có bao nhiêu phần tử trong Map
, chúng ta sử dụng thuộc tính size
myMap.size; // 3
Để kiểm tra xem một key nào đó có tồn tại trong đối tượng Map
hay không, chúng ta sử dụng phương thức has()
myMap.has(1); // true
myMap.has(10); // false
Nếu bạn muốn xóa một cặp key/value nào đó thì sử dụng phương thức delete()
và truyền tên key muốn xóa
myMap.delete(1);
console.log(myMap);
// 0: {2 => "Jill"}
// 1: {"animal" => "Elephant"}
Còn đây là cách xóa toàn bộ sử dụng clear()
myMap.clear();
console.log(myMap);
// Map(0) {size: 0}
1-3. Other Ways to Create a Map Object
Bạn cũng có thể tạo ra đối tượng Map
từ Array như sau:
const myMap = new Map([
[1, 'Jack'],
[2, 'Jill'],
['animal', 'Elephant'],
]);
Khi tạo Map
từ Array, bạn phải tạo một mảng 2 chiều và chỉ định hai phần tử trong mỗi mảng con.
Phần tử đầu tiên sẽ là key, phần tử thứ hai sẽ là value. Bất kì giá trị dư thừa nào trong mảng con sẽ bị bỏ qua.
Ở ví dụ bên dưới, giá trị Johnson
ở mảng đầu tiên sẽ bị bỏ qua (ignored)
const myMap = new Map([
[1, 'Jack', 'Johnson'], // the value 'Johnson' is ignored
[2, 'Jill'],
['animal', 'Elephant'],
]);
Vì ta có thể tạo ra đối tượng Map
từ Array nên chúng ta cũng có thể tạo nó từ Object. Đầu tiên ta cần chuyển từ Object sang Array sử dụng phương thức Object.entries()
const person = {
'name': 'Jack',
'age': 20,
}
const myMap = new Map(Object.entries(person));
console.log(myMap); // Map(2) { 'name' => 'Jack', 'age' => 20 }
1-4. Iterate Map Object
Để duyệt qua các phần tử trong đối tượng Map
ta có thể sử dụng phương thức forEach()
hoặc vòng lặp for ... of
const myMap = new Map([
[1, 'Jack'],
[2, 'Jill'],
['animal', 'Elephant'],
]);
// iterate using the forEach() method
myMap.forEach((value, key) => {
console.log(`${key}: ${value}`);
});
// or using the for .. of loop
for (const [key, value] of myMap) {
console.log(`${key}: ${value}`);
}
Cả 2 cách đều cho ra chung output:
1: Jack
2: Jill
animal: Elephant
1-5. When to Use
Bạn có thể nghĩ đối tượng Map
như là một phiên bản nâng cấp của Object thông thường. Nó có thể sử dụng bất kỳ loại dữ liệu nào làm key, trong khi Object thông thường chỉ dùng string làm key.
Bên trong đối tượng Map
hoạt động hiệu quả hơn khi bạn cần thêm và xóa các key, vì vậy bạn có thể cân nhắc sử dụng nó khi dữ liệu của bạn thay đổi thường xuyên.
Ngoài ra, đối tượng Map
có nhiều phương thức hữu ích cho việc thao tác dữ liệu, chẳng hạn như has()
để kiểm tra xem Map
có chứa một key cụ thể nào không, keys()
để lấy tất cả các keys được định nghĩa trong Map
, values
để lấy tất cả các giá trị, và entries()
để lấy tất cả các cặp key/value.
Tuy nhiên, nếu bạn chỉ muốn tạo một Object mà không cần thao tác gì thêm thì bạn không cần sử dụng đối tượng Map
.
Một ví dụ là khi bạn gửi một yêu cầu mạng bằng phương thức fetch()
. Bạn sẽ tạo một đối tượng và chuyển đổi nó thành chuỗi JSON, vì vậy việc sử dụng đối tượng Map
sẽ không mang lại lợi ích gì.
2. Set Object
Đối tượng Set
cho phép bạn lưu trữ một tập hợp các phần tử, giống như một Array. Những điểm khác biệt giữa Set
và Array là:
Set
yêu cầu tất cả các phần tử phải là duy nhất (unique)Set
có ít phương thức để thao tác dữ liệu hơn.
2-1. How to Create
Để khởi tạo một đối tượng Set
ta sử dụng hàm khởi tạo (constructor) như sau:
const mySet = new Set();
2-2. Methods and Properties
Đối tượng Set
có các phương thức và thuộc tính sau:
add(value)
– Thêm giá trịhas(value)
– Kiểm tra xemSet
có chứa một giá trị cụ thể nào khôngdelete(value)
– Xóa một giá trị cụ thểclear()
– Xóa toàn bộ giá trịkeys()
– Trả về tất cả giá trịvalues()
– Trả về tất cả giá trịentries()
– Trả về tất cả giá trị dưới dạng Array[value, value]
size
– Trả về số lượng phần tử trongSet
Lưu ý rằng keys()
và values()
đều trả về chung kiểu output
const mySet = new Set(['Jack', 'Jill', 'John']);
console.log(mySet.entries());
Output:
[Set Entries] {
[ 'Jack', 'Jack' ],
[ 'Jill', 'Jill' ],
[ 'John', 'John' ]
}
Lưu ý cách các giá trị được lặp lại một lần trong mỗi mảng ở trên. Phương thức entries()
được tạo ra để làm cho Set
giống với đối tượng Map
, nhưng bạn có lẽ không cần đến nó.
Có thêm các phương thức mà bạn có thể sử dụng để tương tác với một đối tượng Set
khác. Chúng ta sẽ thảo luận về chúng trong phần tiếp theo.
Để thêm một phần tử vào đối tượng Set
, bạn có thể sử dụng phương thức add
:
const mySet = new Set();
mySet.add(1);
mySet.add(2);
mySet.add(3);
console.log(mySet); // [1, 2, 3]
Lấy tất cả các giá trị trong Set
mySet.values(); // [Set Iterator] { 'Jack', 'Jill', 'John' }
Kiểm tra xem Set
có chứa giá trị cụ thể nào hay không:
mySet.has('Jack'); // true
mySet.has('Michael'); // false
Cách xóa giá trị:
mySet.delete('Jill');
mySet.clear();
2-3. Composition Methods
Ngoài các phương thức thông thường ở trên, Set
cũng có các phương thức kết hợp mà bạn có thể sử dụng để thực hiện các phép toán lý thuyết tập hợp như hiệu, hợp, và giao (difference, union, intersection)
Bảng tham khảo từ MDN Set documentation:
Ví dụ, bạn có thể lấy một tập hợp chứa các phần tử khác biệt giữa hai tập hợp như sau:
const setA = new Set([1, 2, 3, 4, 5]);
const setB = new Set([4, 5, 6, 7, 8]);
const diffsA = setA.difference(setB); // Set(3) {1, 2, 3}
const diffsB = setB.difference(setA); // Set(3) {6, 7, 8}
Ở đây, phương thức setA.difference(setB)
trả về một Set
chứa các giá trị chỉ có trong đối tượng setA
.
Khi bạn chạy phương thức setB.difference(setA)
, các giá trị ngược lại sẽ được trả về.
Lưu ý rằng các phương thức này là những bổ sung mới cho JavaScript, và tính đến thời điểm này, chỉ có Safari 17 và Chrome 122 hỗ trợ các phương thức này.
Rất có thể, các phương thức này sẽ sớm có trong Node.js.
2-4. Iterate Set Object
Để duyệt qua các phần tử trong đối tượng Set
ta có thể sử dụng forEach()
hoặc vòng lặp for ... of
const mySet = new Set(['Jack', 'Jill', 'John']);
// iterate using the forEach() method
mySet.forEach(value => {
console.log(value);
});
// or using the for .. of loop
for (const value of mySet) {
console.log(value);
}
Output:
Jack
Jill
John
2-5. When to Use
Bạn có thể nghĩ đối tượng Set
như là một phiên bản thay thế của Array thông thường.
Vì đối tượng Set
bỏ qua các giá trị trùng lặp, bạn có thể sử dụng đối tượng này để loại bỏ các phần tử trùng lặp từ một mảng, sau đó chuyển đối tượng Set
trở lại thành mảng:
const myArray = [1, 1, 2, 2, 3, 3];
const uniqueArray = [...new Set(myArray)];
console.log(uniqueArray); // [ 1, 2, 3 ]
Một lý do khác mà bạn có thể muốn sử dụng Set
là khi bạn cần kết hợp nhiều đối tượng set bằng các phương thức kết hợp như union()
và difference()
. Những phương thức này không có sẵn trong mảng.
3. Conclusion
Trong bài viết này chúng ta đã học được cách thức hoạt động của Map
Set
và khi nào nên sử dụng chúng trong code của bạn.
Nếu bạn thích bài viết này và muốn nâng cao kĩ năng JavaScript, tôi khuyên bạn nên xem cuốn sách mới của tôi Beginning Modern JavaScript tại đây
Cuốn sách này được thiết kế đơn giản cho người mới bắt đầu và dễ tiếp cận với bất kì ai muốn học JavaScript. Nó cung cấp hướng dẫn step-by-step giúp bạn hiểu được cách sử dụng JavaScript để tạo ra một ứng dụng web động.
Đây là cam kết của tôi: Bạn sẽ thực sự cảm thấy mình hiểu rõ về JavaScript.
Hẹn gặp lại!
Tham khảo: https://www.freecodecamp.org/news/javascript-map-and-set-objects-explained
All rights reserved