這次要來討論 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
沒有留言:
張貼留言