Sự khác biệt giữa Set và Array trong JavaScript

Trong lập trình JavaScript, SetArray là hai cấu trúc dữ liệu phổ biến để lưu trữ tập hợp các phần tử. Tuy nhiên, mỗi loại có đặc điểm riêng và phù hợp với những tình huống khác nhau. Bài viết này sẽ phân tích chi tiết sự khác biệt giữa chúng, khi nào nên sử dụng từng loại, và cách chuyển đổi qua lại.

1. Những điểm khác biệt cơ bản

Tính duy nhất của phần tử:

  • Set tự động loại bỏ các phần tử trùng lặp. Mỗi giá trị chỉ xuất hiện một lần trong tập hợp.
  • Array cho phép lưu trữ nhiều phần tử giống nhau mà không có hạn chế.

Thứ tự lưu trữ:

  • Set duy trì thứ tự theo thời điểm thêm vào.
  • Array sắp xếp phần tử theo chỉ mục (index), bắt đầu từ 0.

Hiệu suất tìm kiếm:

  • Với Set, phương thức has() hoạt động với độ phức tạp O(1) - tức là thời gian không đổi bất kể kích thước tập hợp.
  • Với Array, phương thức includes() có độ phức tạp O(n) - thời gian tăng tuyến tính theo số lượng phần tử.

Các thao tác cơ bản:

  • Set cung cấp: add() để thêm, delete() để xóa, clear() để xóa tất cả.
  • Array cung cấp: push() thêm vào cuối, pop() xóa từ cuối, splice() chèn/xóa tại vị trí bất kỳ.

Truy cập theo chỉ mục:

  • Set không hỗ trợ truy cập qua index như set[0].
  • Array cho phép truy cập trực tiếp qua chỉ mục như arr[0].

Khả năng lặp:

  • Cả hai đều hỗ trợ for...offorEach.
  • Array có thêm các phương thức xử lý mảng cao cấp như map(), filter(), reduce().

2. Khi nào nên sử dụng Set

Trường hợp cần loại bỏ trùng lặp tự động:

Khi bạn cần thu thập dữ liệu mà không muốn các giá trị trùng nhau xuất hiện nhiều lần.

const danhSachMonAn = new Set(['pho', 'bun', 'pho']);
// Kết quả: Set(2) { 'pho', 'bun' }

Trường hợp cần kiểm tra nhanh sự tồn tại của phần tử:

Khi ứng dụng cần xác nhận một giá trị có trong tập hợp hay không thường xuyên.

const danhSachQuyen = new Set(['view', 'edit', 'delete']);
if (danhSachQuyen.has('edit')) {
  // Thực hiện hành động chỉnh sửa
}

Trường hợp cần thao tác thêm/xóa với hiệu suất cao:

Các opertion adddelete trong Set có độ phức tạp O(1), phù hợp với các ứng dụng cần thay đổi dữ liệu liên tục.

3. Khi nào nên sử dụng Array

Trường hợp cần giữ lại các giá trị trùng lặp:

Khi dữ liệu cần lưu trữ tất cả các lần xuất hiện, không loại bỏ bất kỳ phần tử nào.

Trường hợp cần truy cập theo vị trí hoặc thao tác theo thứ tự:

Khi cần phân trang, sắp xếp, hoặc lấy một phần của tập hợp.

const mangSo = [5, 2, 8, 1, 9];
const sapXep = mangSo.sort((a, b) => a - b);
// Kết quả: [1, 2, 5, 8, 9]

Trường hợp cần xử lý dữ liệu bằng các hàm bậc cao:

Khi cần biến đổi, lọc, hoặc tổng hợp dữ liệu.

const mangChu = ['hello', 'world'];
const vietHoa = mangChu.map(chuoi => chuoi.toUpperCase());
// Kết quả: ['HELLO', 'WORLD']

4. Cách chuyển đổi giữa Set và Array

Từ Array sang Set:

Sử dụng constructor của Set và truyền vào một mảng. Kết quả sẽ tự động loại bỏ các phần tử trùng lặp.

const mangGoc = [10, 20, 20, 30];
const tapHop = new Set(mangGoc);
// Kết quả: Set(3) { 10, 20, 30 }

Từ Set sang Array:

Có hai cách phổ biến để chuyển đổi:

const tapHop = new Set([100, 200, 300]);

// Cách 1: Sử dụng Array.from()
const mangMoi = Array.from(tapHop);
// Kết quả: [100, 200, 300]

// Cách 2: Sử dụng toán tử spread
const mangKhac = [...tapHop];
// Kết quả: [100, 200, 300]

5. Ví dụ kết hợp sử dụng

Loại bỏ trùng lặp trong mảng:

const mangCanLoc = [1, 2, 2, 3, 3, 3];
const mangDuyNhat = [...new Set(mangCanLoc)];
// Kết quả: [1, 2, 3]

Thực hiện các phép toán tập hợp:

const tapA = new Set([1, 2, 3, 4]);
const tapB = new Set([3, 4, 5, 6]);

// Hợp nhất
const hopNhat = new Set([...tapA, ...tapB]);
// Kết quả: Set(6) { 1, 2, 3, 4, 5, 6 }

// Giao nhau
const giaoNhau = new Set([...tapA].filter(giaTri => tapB.has(giaTri)));
// Kết quả: Set(2) { 3, 4 }

// Hiệu (A - B)
const hieuAB = new Set([...tapA].filter(giaTri => !tapB.has(giaTri)));
// Kết quả: Set(2) { 1, 2 }

6. Lưu ý quan trọng

  • Ưu tiên Set khi cần loại bỏ trùng lặp, tìm kiếm nhanh, hoặc thao tác thêm/xóa với tần suất cao.
  • Ưu tiên Array khi cần giữ lại các giá trị trùng, truy cập qua index, hoặc sử dụng các phương thức xử lý dữ liệu bậc cao.
  • Để loại bỏ trùng lặp trong mảng: [...new Set(mangGoc)]
  • Để chuyển Set thành mảng: Array.from(tapHop) hoặc [...tapHop]

Thẻ: JavaScript set array Collection Data-Structures

Đăng vào ngày 21 tháng 7 lúc 02:09