由於 JSON 的資料有很多需要不同的欄目排序來檢查的資料,本來打算使用資料庫編寫 SQL 的 ORDER BY 來進行排序
但 JSON 資料要經常更新,要經常更新資料庫再讀取資料感覺有點累贅,所以在下打算不使用資料庫
在下翻查 PHP 官方文件時發現 array_multisort 能達到效果
例如閣下的 array 像
$array = array( array( 'id' => 1, 'age' => 18, 'height' => 180, ), array( 'id' => 2, 'age' => 22, 'height' => 160, ), array( 'id' => 3, 'age' => 18, 'height' => 160, ), array( 'id' => 4, 'age' => 22, 'height' => 180, ), );若閣下需要將 $array 以 age 倒序、height 順序
需要先將 age 及 height 各獨立成 array
$age = array(); $height = array(); foreach ($array as $key => $value){ $age[$key] = $value['age']; $height[$key] = $value['height']; }最後使用 array_multisort
array_multisort($age, SORT_DESC, $height, SORT_ASC, $array);但問題是
使用者不能確定排序的欄目數量,若要改變方法,便需要借用的功能就需要借用 call_user_func_array
call_user_func_array 能以 callback 的方法使用指定功能,並且能接收不確定長度的參數
function array_orderby($array, $orders){ if (count($orders) > 0){ $fields = array(); foreach ($array as $key => $value){ foreach ($value as $k => $v){ $fields[$k][$key] = $v; } } $params = array(&$array); foreach (array_reverse($orders) as $key => $value){ if (isset($fields[$key])){ array_unshift($params, $value); array_unshift($params, $fields[$key]); } } call_user_func_array('array_multisort', $params); } return $array; }功能中,由於 $array 需要 pass by referece 才能傳回新排序資料
因此 $params 作為 array_multisort 經 call_user_func_array 需要以 &$array 的加入至 $params 中
而 &$array 需要成為 $params 的最後一個元素,所以 $params 需要使用 array_reverse 及 array_unshift 的方法倒序將參數加入
當需要排序時,只需要調用 array_orderby 即可
$orders = array( 'age' => SORT_DESC, 'height' => SORT_ASC, ); $array = array_orderby($array, $orders);然而在模擬操作上與真正的 SQL ORDER BY 仍有些微分別
例如資料庫加入資料本身都有次序
在沒有指定排序欄目
例如
SELECT * FROM `array`;與
print_r($array);是相同
但當有指定排序欄目
例如
SELECT * FROM `array` ORDER BY `age` DESC ;與
print_r(array_orderby($array, array('age' => SORT_DESC)));有機會有分別,但由於測試的資料量太少,未必有顯著的分別
原因是 age 經排序後,遇到相同的 age 後沒有其他指定的排序方法;或欄目的資料並非數值
便會由 SQL 及 PHP 各自的方式處理,但這種方式未必相同
沒有留言 :
張貼留言