Làm thế nào ghép (concat) mảng trong Javascript?

1
Dịch vụ dạy kèm gia sư lập trình
Bài này thuộc phần 9 của 10 phần trong series Tự học Javascript cơ bản

Việc phải ghép nối nhiều mảng thành một mảng duy nhất là một trong những task mà bạn rất hay gặp. Trong javascript, bạn có khá nhiều cách tiếp cận để thực hiện việc này. Bạn có thể chỉnh sửa trực tiếp trên mảng đầu vào, hoặc giữ nguyên tất cả các mảng đầu vào và trả về một mảng mới.

Trong bài viết này, chúng ta sẽ cùng nhau so sánh các cách tiếp cận đó, xem cách nào hay hơn nhé:

  • Phương pháp 1: Nối các phần tử vào một mảng hiện có bằng Array.prototype.push()
  • Phương pháp 2: Nối các phần tử vào một mảng mới bằng Array.prototype.push()
  • Phương pháp 3: Sử dụng prototype concat()
  • Phương pháp 4: Sử dụng toán từ spread (…)

Chúng ta cùng nhau khám phá nhé!

Nối các phần tử vào một mảng hiện có bằng Array.prototype.push()

Đầu tiên, cũng là phương pháp cổ điển nhất. Đó là sử dụng hàm Array.prototype.push(). Giả sử, chúng ta có 2 mảng cần ghép nối sau:

const array1 = [1, 2, 3];
const array2 = [4, 5, 6];

Suy nghĩ đầu tiên mà bạn nghĩ tới là gì? Có phải là sẽ duyệt một mảng và ghép từng phần tử vào mảng còn lại, đúng không?

for (const element of array2) {
  array1.push(element);
}

Ở đây, mình cải tiến mã nguồn cho đẹp hơn một chút, thay vì phải dùng vòng for, chúng ta sử dụng toán tử spread (…)

array1.push(...array2);

Kết quả bạn nhận được là tương tự nhau, mảng array1 giờ chứa tất cả phần tử của cả 2 mảng, còn mảng array2 thì giữ nguyên.

array1; // [1, 2, 3, 4, 5, 6]
array2; // [4, 5, 6]

Đôi khi, việc thay đổi nội dung của mảng đích không phải là điều tốt. Tại sao ư?

Bởi vì, khi bạn viết một hàm  nhận các đối số truyền vào. Tất cả thay đổi chỉ nên xảy ra bên trong hàm đó mà thôi, khi kết thúc hàm, đối số nên được giữ nguyên giá trị, điều này để tránh việc gây ảnh hưởng tới các chức năng khác, khi mà chúng cũng sử dụng giá trị của đối số đó.

Đó là lý do vì sao chúng ta nghĩ tới giải pháp tiếp theo sau đâu.

Nối các phần tử vào một mảng mới bằng Array.prototype.push()

Để giải quyết yêu cầu không làm thay đổi bất kỳ nội dung của mảng truyền vào, chúng ta đơn giản là tạo một mảng rỗng mới. Sau đó, sẽ lần lượt thêm các phần tử của hai mảng kia vào mảng rỗng đó.

const concatenated = [];
concatenated.push(...array1);
concatenated.push(...array2);

Đây là kết quả khi thực hiện:

array1; // [1, 2, 3]
array2; // [4, 5, 6]
concatenated; // [1, 2, 3, 4, 5, 6]

Sử dụng Array.prototype.concat()

Lúc trước, chúng ta sử dụng hàm push() để nối hai mảng với nhau. Giờ mình cho bạn thêm một lựa chọn nữa. Đó là sử dụng Array.prototype.concat().

Vẫn lấy ví dụ là cần ghép nối hai mảng sau:

const array1 = [1, 2, 3];
const array2 = [4, 5, 6];

Chúng ta gọi hàm concat() của mảng  array1 và truyền array2 vào.

const concatenated = array1.concat(array2);

Vì hàm concat() là hàm non-mutating, tức là hàm không làm thay đổi nội dung giá trị truyền vào. Do đó, kết quả chúng ta nhận được giống như phương pháp thứ 2 mà mình đã trình bày ở trên.

array1; // [1, 2, 3]
array2; // [4, 5, 6]
concatenated; // [1, 2, 3, 4, 5, 6]

Cũng giống như hàm push(), hàm concat() chấp nhận nhiều tham số nên bạn có thể ghép nối bao nhiêu mảng cùng lúc cũng được.

const array1 = [1, 2, 3];
const array2 = [4, 5, 6];
const array3 = [7, 8, 9];
const concatenated = array1.concat(array2, array3);

Sau đây là một thủ thuật nhỏ: Cách để bạn làm phẳng một mảng lồng nhau bằng hàm concat. Ví dụ: mình có một mảng với các phần tử là các mảng như sau:

arrays; // [[1, 2, 3], [4, 5, 6], [7, 8, 9]]

Bùm! Cách làm đơn giản như sau:

const concatenated = [].concat(...arrays);

Và đây là kết quả bạn nhận được

concatenated; // [1, 2, 3, 4, 5, 6, 7, 8, 9]

Sử dụng toán từ spread(…)

Phần cuối cùng bài viết, chúng ta sẽ sử dụng toán từ spread(…) để ghép nối hai mảng. Cú pháp như sau:

const concatenated = [...array1, ...array2];

Điều tuyệt vời của toán tử spread là chúng có thể gọi iteration protocol của phần tử mà nó đang thao tác. Điều này có nghĩa là toán tử spread có khả năng hoạt động với bất kỳ iterable nào, không chỉ iterable của array.

Mình sẽ lấy một ví dụ sử dụng toán tử spread(…) để ghép nối hai mảng, đồng thời loại bỏ những phần tử bị trùng lặp, đảm bảo mỗi phần tử trong mảng là duy nhất (unique) bằng cách kết hợp spread(…) với Set iterable.

const array1 = [1, 2, 3];
const array2 = [2, 3, 4];
const uniques = [...new Set([...array1, ...array2])];

Kết quả thu được như sau:

array1; // [1, 2, 3]
array2; // [2, 3, 4]
uniques; // [1, 2, 3, 4]

Tạm kết

Qua bài viết này, mình đã giới thiệu một số phương pháp để bạn có thể ghép nối nhiều mảng lại thành một.

Tùy vào cách tiếp cận hoặc yêu cầu cụ thể của dự án mà bạn chọn cho mình một cách viết hợp lý nhất nhé.

😌 Đọc thêm:

Xem tiếp các bài trong Series
Phần trước: 7 sai lầm lớn khiến việc học Javascript như “nước đổ lá khoai”Phần kế tiếp: Khái niệm Hoisting Javascript là gì? Tại sao lại cần chú ý!
Dịch vụ phát triển ứng dụng mobile giá rẻ - chất lượng
Bài trướcGiải thích chi tiết về Launch Mode và Tasks trong Android
Bài tiếp theoMẹo viết code Kotlin cho Android developer không nên bỏ qua
Tên đầy đủ là Dương Anh Sơn. Tốt nghiệp ĐH Bách Khoa Hà Nội. Mình bắt đầu nghiệp coder khi mà ra trường chẳng xin được việc đúng chuyên ngành. Mình tin rằng chỉ có chia sẻ kiến thức mới là cách học tập nhanh nhất. Các bạn góp ý bài viết của mình bằng cách comment bên dưới nhé !

1
Bình luận. Cùng nhau thảo luận nhé!

avatar
  Theo dõi bình luận  
Mới nhất Cũ nhất Nhiều voted nhất
Thông báo
Thanh
Guest
Thanh

Đơn giản nhỉ