Hôm nay mình xin giới thiệu đến các bạn 3 cách loại bỏ phần tử trùng lặp và chỉ giữ lại những giá trị duy nhất trong mảng của Javascript. Okie, let’s go.
1 | var array = [1, 2, 3, 1, 4, 2, 5]; |
Sử dụng filter
Hàm filter
sẽ tạo ra một mảng mới với kết quả đã được “chọn lọc” từ điều kiện chúng ta đưa vào. Nói cách dễ hiểu, nếu giá trị chúng ta thỏa điều kiện, filter
sẽ “cho phép” thêm phần tử hiện tại này vào mảng mới để trả về, ngược lại không thỏa điều kiện filter
sẽ bỏ qua phần tử đó.
Lợi dụng điểm này chúng ta sẽ viết điều kiện sàng lọc phần tử trùng nhau để filter
bỏ qua, và chỉ trả về mảng với giá trị duy nhất.
Điều kiện sàng lọc là một callback (callback này truyền vào hàm filter
), trong callback này nếu thỏa điều kiện thì trả về true
-> giữ giá trị hiện tại lại, false
-> ngược lại.
Cùng nhìn qua ví dụ dưới đây để hiểu rõ hơn.
1 | const array = [1, 2, 3, 1, 4, 2, 5]; |
Ảnh bên dưới là kết quả console in ra, bạn chỉ cần nhìn sơ qua thôi, nếu chưa hiểu thì hãy đọc tiếp rồi nhìn lại thì bạn sẽ hiểu nhé :v, mình chắc luôn.

Ở chỗ này chúng ta lợi dụng cơ chế làm việc của indexOf
để kiểm tra xem phần tử đó có trùng lặp hay không. Cơ chế hoạt động của indexOf
như sau:
- Bạn truyền vào một giá trị để tìm index
indexOf
lặp hết mảng đó và sẽ trả về index đầu tiên mà nó “kiếm” được trong mảng.
Suy ra nếu index hiện tại (index trong callback của filter
) mà không khớp với index trong mảng (dùng indexOf
) thì giá trị đó đã bị lặp lại.
Các bước sẽ như sau:

Sử dụng reduce
Định nghĩa từ MDN về reduce()
The reduce() method executes a reducer function (that you provide) on each member of the array resulting in a single output value.
Về mục đích hàm reduce
thì nó sẽ giảm dần (thực chất là chạy vòng lặp) các phần tử trong mảng dựa trên callback truyền vào, callback này thường gọi là reducer (dịch ra là hàm giảm). Callback này trả về một kết quả duy nhất. Mình có một bài viết giải thích về hàm này hoạt động tại đây
Thực chất callback reducer giống như cái điều kiện, khi phần tử nào vượt qua được điều kiện nó sẽ cộng dồn vào, để cuối cùng trả về cái đã cộng dồn này. Cộng dồn vào cái gì? Các bạn có thấy tham số thứ hai của hàm reduce không, mảng rỗng đó là giá trị ban đầu để truyền vào callback reducer, tham số nhận giá trị ban đầu này tên là accumulator
, khi thỏa nó sẽ push vào accumulator
, khi lặp xong nó sẽ trả về mảng đã cộng dồn xong.
Giải bài toán loại bỏ phần tử trùng lặp trong mảng này, chúng ta sẽ sử dụng callback reducer với 2 tham số đặt tên là accumulator
(đây mới chính là mảng để cộng dồn kết quả vào) và currentItem
biến này chứa item hiện tại. Nếu item hiện tại chưa có trong mảng accumulator
thì thêm vào accumulator
có rồi thì không thêm.
1 | var array = [1, 2, 3, 1, 4, 2, 5]; |
Step by step:
- Reduce nhận 2 tham số: một là callback, hai là giá trị khởi tạo để truyền vào callback
- Khi lặp, gọi callback truyền vào giá trị khỏi tạo,
accumulator
lúc này sẽ là mảng rỗng. - Check nếu accumulator chứa currentItem (
accumulator.includes(currentItem)
) thì không thêm currentItem vào nữa chỉ trả về mảng accumulator thôi. Ngược lại thêm vào mảng accumulator, cú pháp thêm vào[...accumulator, currentItem]
. - Cứ như vậy lặp hết mảng sẽ trả về được mảng duy nhất không bị lặp phần tử nào.
Đây là kết quả in ra dưới console

Sử dụng Set
Đây là cách hiện đại, cú pháp ngắn gọn, dễ nhớ. Set
là một data Object
mới được giới thiệu trong ES6. Với đặc tính chỉ chứa các giá trị duy nhất (không trùng lặp) và tự động loại bỏ những giá trị trùng lặp ra, khi cố tình truyền vào, nên chúng ta sẽ sử dụng nó để loại trừ phần tử bị trùng trong mảng.
1 | var array = [1, 2, 3, 1, 4, 2, 5]; |
Chúng ta sẽ cũng đi phân tích một chút về cách implement vào bài toán của chúng ta. Có thể thấy nó sẽ diễn ra với hai bước như sau:
- Khởi tạo một object
Set
với giá trị truyền vàoconstructor
là một mảng. Bởi vìSet
chỉ chứa giá trị duy nhất nên cơ chế của nó sẽ tự động loại bỏ những trùng lặp. - Bây giờ chúng ta đã có một
Set
với tất cả trùng lặp đã biến mất, và sử dụng toán tửspread
(…) để destructing nó ra mảng.
Cách viết chi tiết nhất có thể
1 | var array = [1, 2, 3, 1, 4, 2, 5]; |
Ngoài ra thì chúng ta có thể thay thế toán tử spread
bằng cách dùng prototype
có sẵn của Array là Array.from
1 | const array = [1, 2, 3, 1, 4, 2, 5]; |
Kết luận
Bạn có thể tham khảo kết quả benchmark
các cách trên để lựa chọn ra giải pháp ngon lành, phù hợp nhất nhé, link.
P/s: Với mình, mình ưng dùng Set
nhất, vì cú pháp ngắn gọn nhìn đơn giản dễ nhớ và cộng thêm trong NodeJs
mà dùng Set
ngó rất đẹp :D.
Có góp ý hay điều gì đó comment cho mình biết nhá. Thanks đã đọc nè :P.
Updated date: 21.03.2020
Tham khảo
- MDN web docs - filter
- MDN web docs - reduce
- MDN web docs - Set object
- https://medium.com/dailyjs/how-to-remove-array-duplicates-in-es6-5daa8789641c