Menu

PHP array_unique(): xóa giá trị trùng lặp trong mảng

array_unique($array) xóa các giá trị trùng lặp và giữ lần xuất hiện đầu tiên của mỗi giá trị cùng khóa gốc. Tìm hiểu cách đánh số lại kết quả, xóa trùng lặp không phân biệt hoa thường, lọc trùng mảng nhiều chiều, đếm và tìm giá trị trùng.

Trang này có trình soạn thảo chạy trực tiếp. Sửa, chạy và xem đầu ra ngay lập tức.

array_unique($array) trả về mảng đã xóa các giá trị trùng lặp. Lần xuất hiện đầu tiên của mỗi giá trị được giữ lại dưới khóa gốc, các bản sao về sau bị bỏ đi.

Kết quả đầu tiên giữ các khóa 0, 1, 3: những vị trí mà mỗi giá trị xuất hiện lần đầu. Bọc lời gọi trong array_values() khi bạn muốn một danh sách gọn gàng, chẳng hạn trước khi gọi json_encode.

array_unique quyết định hai giá trị giống nhau ra sao

Mặc định, mỗi giá trị được chuyển thành chuỗi rồi các chuỗi được so sánh với nhau. Vì vậy 1, "1" và 1.0 được tính là cùng một giá trị, và giá trị đứng đầu được giữ. Đối số thứ hai thay đổi cách so sánh.

CờHai giá trị bị coi là trùng khi
SORT_STRING (mặc định)(string) $a === (string) $b
SORT_REGULAR$a == $b
SORT_NUMERICchúng bằng nhau khi xét như số

Với chế độ mặc định, "01" được giữ lại vì chuỗi "01" không phải là chuỗi "1". Với SORT_REGULAR nó bị loại, vì "01" == 1 là đúng. So sánh lỏng còn khiến boolean true khớp với mọi giá trị không rỗng. Hãy xem kỹ đầu ra trước khi dựa vào nó với các kiểu dữ liệu lẫn lộn; trang toán tử so sánh giải thích các quy tắc này.

Xóa trùng lặp không phân biệt hoa thường

array_unique phân biệt chữ hoa, chữ thường: "PHP" và "php" là hai giá trị khác nhau. Để coi chúng là trùng nhưng vẫn giữ cách viết gốc của giá trị đầu tiên, hãy tìm các khóa duy nhất trên một bản sao chữ thường rồi giữ những khóa đó từ mảng gốc.

array_map tạo một bản sao chữ thường với cùng các khóa, array_unique giữ khóa của những lần xuất hiện đầu tiên, và array_intersect_key lấy đúng các khóa đó ra khỏi mảng gốc. Với văn bản có dấu như tiếng Việt hoặc tiếng Nhật, dùng mb_strtolower thay cho strtolower.

array_unique với mảng nhiều chiều

Khi không có cờ, array_unique chuyển mỗi hàng thành chuỗi "Array", nên mọi hàng trông giống hệt nhau và chỉ hàng đầu tiên còn lại, kèm cảnh báo "Array to string conversion" cho từng hàng. Truyền SORT_REGULAR để so sánh cả hàng. Để giữ một hàng cho mỗi giá trị của một trường, dùng array_column với null và một khóa chỉ mục sẽ đơn giản hơn.

Cách thứ hai giữ hàng cuối cùng của mỗi email, vì mỗi hàng đến sau ghi đè hàng trước dưới cùng một khóa. Trang array_column giải thích chi tiết về khóa chỉ mục.

Tìm và đếm giá trị trùng lặp

array_count_values() trả về số lần xuất hiện của mỗi giá trị. Lọc lấy những số đếm lớn hơn một là bạn có các giá trị bị trùng.

Phép kiểm tra cuối là một dòng code quen thuộc để biết mảng có giá trị trùng nào hay không.

Lấy giá trị duy nhất nhanh hơn với mảng lớn

array_unique chuyển mọi giá trị thành chuỗi trước khi so sánh, điều này ổn với vài nghìn giá trị. Với danh sách lớn gồm số nguyên hoặc chuỗi, lật mảng sẽ nhanh hơn: giá trị trở thành khóa, mà khóa thì vốn đã duy nhất.

Thời gian đo thay đổi giữa các lần chạy, nhưng cách lật mảng thường nhanh hơn vài lần. Cách này chỉ dùng được với những giá trị có thể làm khóa mảng (số nguyên và chuỗi), và các chuỗi số như "5" sẽ trở về dưới dạng số nguyên.

Câu hỏi thường gặp

array_unique có giữ khóa không?

Có. Hàm giữ lần xuất hiện đầu tiên của mỗi giá trị dưới khóa gốc và bỏ các lần sau, nên dãy khóa có thể bị hở. Dùng array_values(array_unique($arr)) để đánh số lại từ 0.

Dùng array_unique với mảng nhiều chiều như thế nào?

Truyền SORT_REGULAR để so sánh cả hàng: array_unique($rows, SORT_REGULAR). Để giữ một hàng cho mỗi giá trị của một trường, chẳng hạn mỗi email một hàng, hãy đánh chỉ mục các hàng theo trường đó: array_column($rows, null, 'email') giữ hàng cuối cùng của mỗi email.

Làm sao xóa trùng lặp mà không phân biệt chữ hoa, chữ thường?

Tìm các khóa duy nhất trên một bản sao đã chuyển sang chữ thường, rồi giữ những khóa đó từ mảng gốc: array_intersect_key($arr, array_unique(array_map('strtolower', $arr))). Với văn bản ngoài ASCII, dùng mb_strtolower.

Làm sao tìm những giá trị bị trùng trong mảng PHP?

Đếm chúng bằng array_count_values($arr), rồi giữ những số đếm lớn hơn một: array_keys(array_filter(array_count_values($arr), fn($n) => $n > 1)). array_count_values chỉ hoạt động với chuỗi và số nguyên.

Hình minh họa các ngôn ngữ lập trình của Coddy

Học lập trình cùng Coddy

Bắt đầu