2013-02-10 25 views
12
$array = array(1, '1a', '1'); 
var_export(array_unique($array, SORT_REGULAR)); 
  • Kết quả: array (0 => 1, 2 => '1')
  • Trong hướng dẫn PHP: SORT_REGULAR - so sánh các mặt hàng bình thường (không thay đổi các loại).

Logic đằng sau điều này là gì? Tại sao hoặc '1a' bị loại trừ như thế nào?Array_unique SORT_REGULAR cờ

Trả lời

13

Điều này xảy ra bởi vì các tác phẩm của array_uniquefirst sorting the values as strings, sau đó iterating trong mảng được sắp xếp và cho mỗi giá trị trừ từ kết quả tất cả các giá trị liên tiếp mà so sánh tương đương với nó.

Hàm so sánh cho "so sánh bằng" ở trên được chọn theo thông số thứ hai, cho số SORT_REGULAR giống như kiểm tra bình đẳng với ==.

Hành vi này làm phát sinh rất nhiều gotchas. Kể từ khi sắp xếp là quicksort, nó không ổn định. Do đó việc sắp xếp một mảng chứa cả hai số 1'1' không đảm bảo kết quả nào sẽ là kết quả đầu tiên trong kết quả. Điều này có nghĩa là array_unique có thể xuất hiện tùy ý "thích" 1 trong một số trường hợp và '1' ở những trường hợp khác.

Tuy nhiên sự điên rồ tiếp tục: xem xét rằng nếu các loại sản xuất [1, '1', '1a'] sau đó '1a' sẽ không được đưa vào kết quả (nó sẽ so sánh tương đương với 1) trong khi nếu các loại sản xuất ['1', 1, '1a'] sau đó nó sẽ được bao gồm (nó không so sánh với chuỗi '1')!

+0

Sự lặp lại này chỉ xảy ra một lần? Bởi vì sau đó chúng ta sẽ nhận được các giá trị trùng lặp nếu một '1' khác được bao gồm sau' 5' –

+0

@OneTrickPony: Tôi đã không đề cập rõ ràng rằng mảng được sắp xếp đầu tiên (tài liệu có). Nhưng trên suy nghĩ thứ hai nó khá quan trọng bởi vì các loại không ổn định (quicksort), vì vậy hãy để tôi mở rộng câu trả lời một chút. – Jon

+0

@OneTrickPony: Thực ra nó hoạt động hơi khác so với những gì tôi tin - và bạn có lẽ sẽ không ngạc nhiên khi biết rằng hành vi không thể dự đoán được trong những trường hợp như thế này bởi vì, tốt, PHP. – Jon

4

Nếu bạn muốn có thêm một chút kỹ thuật, bạn có thể xem nguồn.

Cờ PHP_SORT_REGULAR chỉ cần yêu cầu array_unique quay trở lại toán tử so sánh chuẩn (==).

Bạn có thể thấy điều này trong nguồn cho array_unique trong đó sử dụng php_set_compare_func:

static void php_set_compare_func(int sort_type TSRMLS_DC) /* {{{ */ 
{ 
switch (sort_type & ~PHP_SORT_FLAG_CASE) { 
... 
    case PHP_SORT_REGULAR: 
    default: 
     ARRAYG(compare_func) = compare_function; 
     break; 
} 

đâu compare_func chỉ là standard comparison function.

Đây có thể là lỗi tài liệu nhiều hơn bất kỳ thứ gì khác. Các bình luận trong tài liệu là một chút nhầm lẫn:

... bằng khi và chỉ khi (string) $ elem1 === (string) $ elem2

Nếu cả hai giá trị này được gộp lại thành chuỗi , thì === là không cần thiết, nhưng nó dẫn đến giả thiết rằng SORT_REGULAR thực hiện so sánh kiểu.