這次要來討論 usort()。
我們假設以下情況依照水果名稱排序:
$fruits = array(
array('id' => 1, 'name' => 'apple'),
array('id' => 2, 'name' => 'orange'),
array('id' => 3, 'name' => 'banana'),
array('id' => 4, 'name' => 'banana'));
usort($fruits, function ($a, $b) {
if ($a['name'] === $b['name']) { return 0; }
return $a['name'] < $b['name'] ? -1 : 1;
});
/**
* Output:
* $fruits = array(
* array('id' => 1, 'name' => 'apple'),
* array('id' => 4, 'name' => 'banana'),
* array('id' => 3, 'name' => 'banana'),
* array('id' => 2, 'name' => 'orange'));
*/
結果似乎有點不符預期,banana (id=3) 不是出現在 banana (id=4) 前面。
再測試一次,這次改為回傳總是 0,即左右等值,所以預期順序應該不會有任何變化。
但是做完 usort() 之後,結果卻是幫我們進行一次反向排序。
usort($fruits, function ($a, $b) { return 0; });
/**
* Expect:
* $fruits = array(
* array('id' => 1, 'name' => 'apple'),
* array('id' => 2, 'name' => 'orange'),
* array('id' => 3, 'name' => 'banana'),
* array('id' => 4, 'name' => 'banana'));
* Acutal:
* $fruits = array(
* array('id' => 4, 'name' => 'banana'),
* array('id' => 3, 'name' => 'banana'),
* array('id' => 2, 'name' => 'orange'),
* array('id' => 1, 'name' => 'apple'));
*/
查閱 PHP Manual 之後,
發現到這段說明:
Note: If two members compare as equal, their relative order in the sorted array is undefined.
原來等值並沒有規定怎麼處理。
由於等值並沒有規範,所以我們需要再做一些判斷,才會是我們預期的結果。
usort($fruits, function ($a, $b) {
if ($a['name'] === $b['name']) { return $a['id'] > $b['id']; }
return $a['name'] < $b['name'] ? -1 : 1;
});
/**
* Output:
* $fruits = array(
* array('id' => 1, 'name' => 'apple'),
* array('id' => 3, 'name' => 'banana'),
* array('id' => 4, 'name' => 'banana'),
* array('id' => 2, 'name' => 'orange'));
*/
PHP 5.3.24 (cli) (built: Jun 10 2013 16:42:20)
Copyright (c) 1997-2013 The PHP Group
Zend Engine v2.3.0, Copyright (c) 1998-2013 Zend Technologies
with Xdebug v2.2.0rc1, Copyright (c) 2002-2012, by Derick Rethans