二維數組根據某個字段排序有兩種辦法,一種是通過sort自己寫代碼,一種是直接用array_multisort排序函數
一. 手寫arraysort
PHP的一維數組排序函數:
sort 對數組的值按照升序排列(rsort降序),不保留原始的鍵
ksort 對數組的鍵按照升序排列(krsort降序) 保留鍵值關系
asort 對數組的值按照升序排列(arsort降序),保留鍵值關系
方法: 取出要排序的值組成值數組(為一維數組),按要求對值進行排序(保持鍵值關系),遍歷值數組,按照鍵對應賦值給結果數組。
function arraySort($array,$keys,$sort='asc') { $newArr = $valArr = array(); foreach ($array as $key=>$value) { $valArr[$key] = $value[$keys]; } ($sort == 'asc') ? asort($valArr) : arsort($valArr); reset($valArr); foreach($valArr as $key=>$value) { $newArr[$key] = $array[$key]; } return $newArr; }
二. 通過array_multisort 進行數組字段排序
這里也是本篇主要要說的。
官網對array_multisort函數的解釋: 對多個數組或多維數組進行排序
bool array_multisort ( array $ar1 [, mixed $arg [, mixed $... [, array $... ]]] )
成功時返回 TRUE, 或者在失敗時返回 FALSE.
array_multisort() 可以用來一次對多個數組進行排序,或者根據某一維或多維對多維數組進行排序。關聯(string)鍵名保持不變,但數字鍵名會被重新索引。
輸入數組被當成一個表的列並以行來排序——這類似於 SQL 的 ORDER BY 子句的功能。第一個數組是要排序的主要數組。數組中的行(值)比較為相同的話就按照下一個輸入數組中相應值的大小來排序,依此類推。
本函數的參數結構有些不同尋常,但是非常靈活。第一個參數必須是一個數組。接下來的每個參數可以是數組或者是下面列出的排序標志。
排序順序標志:
- SORT_ASC - 按照上升順序排序
- SORT_DESC - 按照下降順序排序
排序類型標志:
- SORT_REGULAR - 將項目按照通常方法比較
- SORT_NUMERIC - 將項目按照數值比較
- SORT_STRING - 將項目按照字符串比較
每個數組之后不能指定兩個同類的排序標志。每個數組后指定的排序標志僅對該數組有效 - 在此之前為默認值 SORT_ASC 和 SORT_REGULAR。
例1:
$ar1 = array("10", 101, 100, 6); $ar2 = array(1, 3, 6, 5); array_multisort($ar1, $ar2); print_r($ar1); print_r($ar2);
第二個數組中的項目順序完全和第一個數組中相應的項目順序一致。
Array ( [0] => 6 [1] => 10 [2] => 100 [3] => 101 ) Array ( [0] => 5 [1] => 1 [2] => 6 [3] => 3 )
例2:
$ar = array( array("b10", 'c11', 101, 100, "a"), array(1, 2, "2", 9, 5) ); array_multisort($ar[0], SORT_ASC, SORT_STRING, $ar[1], SORT_NUMERIC, SORT_DESC); print_r($ar);
經過排序后,第一個數組將包含 "b10", 'c11',101,100,"a"(作為字符串上升排序),第二個數組將包含 1,2,"2",9,5(作為數值下降排序)。
Array ( [0] => Array ( [0] => 100 [1] => 101 [2] => a [3] => b10 [4] => c11 ) [1] => Array ( [0] => 9 [1] => 2 [2] => 5 [3] => 1 [4] => 2 ) )
例3:(我們要的結果)
$data[] = array('customer_name' => '小李', 'money' => 12, 'distance' => 2, 'address' => '長安街C坊'); $data[] = array('customer_name' => '王曉', 'money' => 30, 'distance' => 10, 'address' => '北大街30號'); $data[] = array('customer_name' => '趙小雅', 'money' => 89, 'distance' => 6, 'address' => '解放路恆基大廈A座'); $data[] = array('customer_name' => '小月', 'money' => 150, 'distance' => 5, 'address' => '天橋十字東400米'); $data[] = array('customer_name' => '李亮亮', 'money' => 45, 'distance' => 26, 'address' => '天山西路198弄'); $data[] = array('customer_name' => '董娟', 'money' => 67, 'distance' => 17, 'address' => '新大南路2號'); // 取得列的列表 foreach ($data as $key => $row) { $distance[$key] = $row['distance']; $money[$key] = $row['money']; } array_multisort($distance, SORT_DESC, $data); print_r($data);
$data包含有行的數組,但是 array_multisort() 需要一個包含列的數組,因此用foreach來取得列,然后排序。
所有,我們將array_multisort() 封裝下:
/** * 二維數組根據某個字段排序 * @param array $array 要排序的數組 * @param string $keys 要排序的鍵字段 * @param string $sort 排序類型 SORT_ASC SORT_DESC * @return array 排序后的數組 */ function arraySort($array, $keys, $sort = SORT_DESC) { $keysValue = []; foreach ($array as $k => $v) { $keysValue[$k] = $v[$keys]; } array_multisort($keysValue, $sort, $array); return $array; }
繼續使用上例中的$data 數組
# 按距離降序排序 $a = arraySort($data, 'distance', SORT_DESC); print_r($a); # 按money升序排序 $b = arraySort($data, 'money', SORT_ASC); print_r($b);
效果:
Array ( [0] => Array ( [customer_name] => 李亮亮 [money] => 45 [distance] => 26 [address] => 天山西路198弄 ) [1] => Array ( [customer_name] => 董娟 [money] => 67 [distance] => 17 [address] => 新大南路2號 ) [2] => Array ( [customer_name] => 王曉 [money] => 30 [distance] => 10 [address] => 北大街30號 ) [3] => Array ( [customer_name] => 趙小雅 [money] => 89 [distance] => 6 [address] => 解放路恆基大廈A座 ) [4] => Array ( [customer_name] => 小月 [money] => 150 [distance] => 5 [address] => 天橋十字東400米 ) [5] => Array ( [customer_name] => 小李 [money] => 12 [distance] => 2 [address] => 長安街C坊 ) )
Array ( [0] => Array ( [customer_name] => 李亮亮 [money] => 45 [distance] => 26 [address] => 天山西路198弄 ) [1] => Array ( [customer_name] => 董娟 [money] => 67 [distance] => 17 [address] => 新大南路2號 ) [2] => Array ( [customer_name] => 王曉 [money] => 30 [distance] => 10 [address] => 北大街30號 ) [3] => Array ( [customer_name] => 趙小雅 [money] => 89 [distance] => 6 [address] => 解放路恆基大廈A座 ) [4] => Array ( [customer_name] => 小月 [money] => 150 [distance] => 5 [address] => 天橋十字東400米 ) [5] => Array ( [customer_name] => 小李 [money] => 12 [distance] => 2 [address] => 長安街C坊 ) ) Array ( [0] => Array ( [customer_name] => 小李 [money] => 12 [distance] => 2 [address] => 長安街C坊 ) [1] => Array ( [customer_name] => 王曉 [money] => 30 [distance] => 10 [address] => 北大街30號 ) [2] => Array ( [customer_name] => 李亮亮 [money] => 45 [distance] => 26 [address] => 天山西路198弄 ) [3] => Array ( [customer_name] => 董娟 [money] => 67 [distance] => 17 [address] => 新大南路2號 ) [4] => Array ( [customer_name] => 趙小雅 [money] => 89 [distance] => 6 [address] => 解放路恆基大廈A座 ) [5] => Array ( [customer_name] => 小月 [money] => 150 [distance] => 5 [address] => 天橋十字東400米 ) )
