給定一個二維數組,請根據指定的數組key
,寫出最優的排序。排序條件age asc,sex desc
,指定數組以下:php
$arr = [ ['id'=>1, 'age'=>1, 'sex'=>6, 'name'=>'a'], ['id'=>2, 'age'=>3, 'sex'=>1, 'name'=>'c'], ['id'=>3, 'age'=>3, 'sex'=>1, 'name'=>'b'], ['id'=>4, 'age'=>2, 'sex'=>1, 'name'=>'d'], ];
估計你們都沒有什麼問題,排序嘛,簡單的不要不要的:mysql
array_multisort(array_column($arr,'age'),SORT_ASC,array_column($arr,'sex'), SORT_DESC, $mylist);
這應該是最簡單的方式了,直接使用php現成的函數,快捷的不要不要的。面試
$sort = []; foreach($arr as $k=>$v) { $sort['age'][$k] = $v['age']; $sort['sex'][$k] = $v['sex']; } array_multisort($sort['age'],SORT_ASC,$sort['sex'],SORT_DESC,$mylist);
嗯,勉強看的過去,可是感受有點不優雅。sql
$orders=['age'=>'asc','sex'=>'desc']; usort($arr, function($a, $b) use($orders) { $result = []; foreach ($orders as $key=>$value) { list($field, $sort) = [$key,$value]; if (!(isset($a[$field]) && isset($b[$field]))) { continue; } if (strcasecmp($sort, 'desc') === 0) { $tmp = $a; $a = $b; $b = $tmp; } if (is_numeric($a[$field]) && is_numeric($b[$field]) ) { $result[] = $a[$field] - $b[$field]; } else { $result[] = strcmp($a[$field], $b[$field]); } } return implode('', $result); });
三種方式均可以,都比較簡單,那麼問題來了。數據庫
若是排序數組不是固定的呢,排序數組是動態從數據庫查詢出來,排序條件也不是固定的呢,那麼咱們確定要封裝函數,若是使用
php
內置函數:
function _sort(){ ...... array_multisort(...) }
這裏咱們就看出問題來了,array_multisort
的參數不固定啊,使用有兩個方法:func_get_args()
和...$arg
,放棄func_get_args()
,由於沒有辦法使用。若是是本身寫的函數也建議不用,由於使用func_get_args()
,容易讓函數看上去是不須要傳遞參數的。若是你在寫大量代碼的時候,進行縮放的時候,也很難了解這個函數參數大概細節。這是很是不方便的。因此函數以下:數組
function _sort( &$arr, $sorts ) { $sortParams = []; foreach ( $sorts as $key => $v ) { $sortParams[] = array_column($arr, $key); $sortParams[] = strcasecmp($v, 'desc') === 0 ? SORT_DESC : SORT_ASC; } array_push($sortParams, $arr); array_multisort(...$sortParams); } _sort(['age'=>'asc','name'=>'desc','sex'=>'asc']);
看是去很好對吧,可是運行才知道,沒有效果,難道是array_multisort
不支持...$arg
,查看了手冊,沒看到說明,😔,那就放棄自帶的函數,想本身寫好了:函數
function arrayOrderBy(array &$arr, $order = null) { if (is_null($order)) { return $arr; } $orders = explode(',', $order); usort($arr, function($a, $b) use($orders) { $result = array(); foreach ($orders as $value) { list($field, $sort) = array_map('trim', explode(' ', trim($value))); if (!(isset($a[$field]) && isset($b[$field]))) { continue; } if (strcasecmp($sort, 'desc') === 0) { $tmp = $a; $a = $b; $b = $tmp; } if (is_numeric($a[$field]) && is_numeric($b[$field]) ) { $result[] = $a[$field] - $b[$field]; } else { $result[] = strcmp($a[$field], $b[$field]); } } arrayOrderBy($arr, 'age asc,sex asc,name desc');
其實這就是一道面試題,大概意思讓用PHP
寫一個相似mysql
的order by
的功能,其實也很簡單。.net