openplanning

Hướng dẫn JavaScript Set Collection

  1. Collections - Set
  2. Các phương thức của Set
  3. WeakSet

1. Collections - Set

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ề Set.
Set
Set là một cấu trúc dữ liệu được giới thiệu trong ECMAScript6, sau đây là các đặc điểm của Set:
  • Set là một danh sách chứa các phần tử, nhưng không cho phép trùng lặp.
  • Set không đánh chỉ số cho các phần tử.
  • Set là một danh sách có thứ tự (Ordered), điều đó có nghĩa là phần tử được thêm vào trước sẽ đứng trước, phần tử được thêm vào sau sẽ đứng sau.
Constructors:
Tạo đối tượng Set thông qua constructor của lớp Set:
new Set( [iterable] )
Các tham số:
  • iterable - Nếu đối tượng này được truyền (pass) vào constructor của Set tất cả các phần tử có nó sẽ được thêm vào Set. Ngược lại nếu bạn không chỉ định tham số này, hoặc giá trị của nó là null thì đối tượng Set được tạo ra sẽ rỗng (empty).
Properties:
set-example.js
// Create a Set from an Array
var fruits = new Set( ["Apple","Banana","Papaya"] );

console.log(fruits); // Set { 'Apple', 'Banana', 'Papaya' }
Property
Mô tả
size
Property này trả về số phần tử của đối tượng Set.
set-size-example.js
// Create a Set from an Array
var fruits = new Set( ['Apple','Banana','Papaya'] );

var size = fruits.size;

console.log(size); // 3
for..of
Bạn có thể sử dụng vòng lặp for...of để lặp trên các phần tử của Set.
set-for-of-loop-example.js
// Create a Set from an Array
var fruits = new Set( ["Apple","Banana","Papaya"] );

for(let fruit of fruits)  {

  console.log(fruit);

}
Output:
Apple
Banana
Papaya

2. Các phương thức của Set

add(value)
Thêm một phần tử vào phía cuối của Set nếu phần tử này không tồn tại trong Set. Và trả về đối tượng Set này.
set-add-example.js
// Create a Set from an Array
var fruits = new Set( ["Apple","Banana","Papaya"] );

// Append an Element to the Set and returns this Set.
var thisFruits = fruits.add("Cherry");

console.log(fruits); // Set { 'Apple', 'Banana', 'Papaya', 'Cherry' }

// 'Set' does not allow duplicates
fruits.add("Banana");

console.log(fruits); // Set { 'Apple', 'Banana', 'Papaya', 'Cherry' }
Output:
Set { 'Apple', 'Banana', 'Papaya', 'Cherry' }
Set { 'Apple', 'Banana', 'Papaya', 'Cherry' }
delete(value)
Phương thức này dùng để xóa một phần tử ra khỏi Set. Phương thức trả về true nếu tìm thấy phẩn tử để xóa, ngược lại trả về false.
set-delete-example.js
// Create a Set from an Array
var fruits = new Set( ["Apple","Banana","Papaya"] );

console.log(fruits); // Set { 'Apple', 'Banana', 'Papaya' }

// Delete an element:
var deleted = fruits.delete("Banana");

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

console.log(fruits); // Set { 'Apple', 'Papaya' }
clear()
Loại bỏ tất cả các phần tử ra khỏi Set.
set-clear-example.js
// Create a Set from an Array
var fruits = new Set( ["Apple","Banana","Papaya"] );

console.log(fruits); // Set { 'Apple', 'Banana', 'Papaya' }

// Remove all elements.
fruits.clear();

console.log(fruits); // Set { }

console.log("Size after clear: " + fruits.size);
entries()
Phương thức này trả về một đối tượng Iterator mới, mà mỗi entry (thực thể) của nó chứa một mảng 2 phần tử [value, value], thứ tự của các entry vẫn được giữ nguyên giống với thứ tự các phần tử trong đối tượng Set. (Xem hình minh họa dưới đây).
set-entries-example.js
// Create a Set from an Array
var fruits = new Set( ["Apple","Banana","Papaya"] );

console.log(fruits); // Set { 'Apple', 'Banana', 'Papaya' }

// Iterator Object:
var iteratorEntries = fruits.entries();

var entry;

while( !(entry = iteratorEntries.next() ).done )  {

    console.log(entry.value); // [ 'Apple', 'Apple' ]
}
has(value)
Phương thức này kiểm tra xem một giá trị cho bởi tham số có tồn tại trong Set hay không. Trả về true nếu tồn tại, ngược lại trả về false.
set-has-example.js
// Create a Set from an Array
var fruits = new Set( ["Apple","Banana","Papaya"] );

var has = fruits.has("Banana");

console.log(has); // true
forEach(callbackFn[, thisArg])
Phương thức này sẽ gọi hàm callbackFn một lần đối với mỗi phần tử của Set.
mySet.forEach(callbackFn [, thisArg])
Các tham số:
  • callbackFn - Hàm này sẽ được gọi một lần ứng với mỗi phần tử của đối tượng Set.
  • thisArg - Tham số được sử dụng như this khi thực thi hàm callbackFn.
set-forEach-example.js
// Create a Set from an Array
var fruits = new Set( ["Apple","Banana","Papaya"] );

console.log(fruits); // Set { 'Apple', 'Banana', 'Papaya' }

function showFruit(fruit, thisSet) {
  console.log("Fruit: " + fruit);
}

// Or Call: fruits.forEach(showFruit);
fruits.forEach(showFruit, fruits);
key() & values()
Phương thức key() & values() trả về một đối tượng Iterator mới, mà mỗi phần tử của Iterator có dạng {value: aValue, done: false}.
set-values-example.js
// Create a Set from an Array
var fruits = new Set( ["Apple","Banana","Papaya"] );


var fruitIterator = fruits.values();

var entry;
while ( !(entry = fruitIterator.next()).done)  {
   console.log(entry); // { value: 'Apple', done: false }
   console.log(entry.value); // Apple
}
Output:
{ value: 'Apple', done: false }
Apple
{ value: 'Banana', done: false }
Banana
{ value: 'Papaya', done: false }
Papaya
mySet[Symbol.iterator]
Symbol.iterator là một property đặc biệt của đối tượng Set. Theo mặc định, giá trị của mySet[Symbol.iterator] là phương thức values() của đối tượng mySet.
set-symbol-iterator-example.js
// Create a Set from an Array
var fruits = new Set( ["Apple","Banana","Papaya"] );

// Same as: fruits.values()
var fruitIterator = fruits[Symbol.iterator]();

var entry;
while ( !(entry = fruitIterator.next()).done)  {
   console.log(entry); // { value: 'Apple', done: false }
   console.log(entry.value); // Apple
}

3. WeakSet

Về cơ bản WeakSet khá giống với Set, nhưng nó có các khác biệt sau:
  • Các phần tử của WeakSet phải là các đối tượng, nó không thể là một kiểu nguyên thủy (Primitive).
  • Các phần tử của WeakSet 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 độc lập để loại bỏ các đối tượng không còn được sử dụng trong chương trình.
  • WeakSet không hỗ trợ property: size, vì vậy bạn không thể biết nó có bao nhiêu phần tử.
  • Có nhiều phương thức được có trong lớp Set nhưng không có lớp WeakSet, chẳng hạn values(), keys(), clear(),..
Chú ý: Bạn không thể sử dụng vòng lặp for..of đối với WeakSet, và cũng không có cách nào để bạn lặp (iterate) trên các phần tử của WeakSet.
Tạo một đối tượng WeakSet.
new Set( [iterable] )
Các tham số:
  • iterable - Nếu đối tượng này được truyền (pass) vào constructor của WeakSet tất cả các phần tử có nó sẽ được thêm vào Set. Ngược lại nếu bạn không chỉ định tham số này, hoặc giá trị của nó là null thì đối tượng Set được tạo ra sẽ rỗng (empty).
Methods:
Số lượng các phương thức của WeakSet ít hơn so với số lượng các phương thức của Set:
  • WeakSet.add(element)
  • WeakSet.delete(element)
  • WeakSet.has(element)
Các phần tử trong WeakSet phải là các đối tượng, chúng không thể là các kiểu nguyên thủy (Primitive).
let w = new WeakSet();
w.add('a'); // TypeError: Invalid value used in weak set

let s = new Set();
s.add('a'); // Works
weakset-example.js
var element1 = {}; // An Object
var element2 = {foo: "bar"};
var element3 = {bar: "foo"};


var myWeakSet = new WeakSet( [element1, element2] );
myWeakSet.add(element3);

console.log(myWeakSet.has(element2)); // true

Các hướng dẫn ECMAScript, Javascript

Show More