因为项目需求,萌生了写一个根据多个字段进行二维数组排序函数的想法,网上查找了下,全都是使用array_multisort实现的,遂自己写了一个不使用array_multisort函数的实现方式
使用eval判断大小,好处是代码少一些
/**
* 二维数组多字段排序
* @param array $array
* @param array $sort:['a'=>'desc','b'=>'asc','d'=>'desc']
* @return array
*/
function sortArrByManyField(array $array, $sort = [])
{
if (!$sort) {
return $array;
}
$array = array_values($array);
for ($i=0; $i < count($array); ++$i) {
foreach ($sort as $key=>$order){
$condition = strtolower($order) == 'desc'?'>=':'<=';
if(!isset($array[$i+1])){
break 2;
}
$return = eval("return {$array[$i][$key]} {$condition} {$array[$i+1][$key]};");
if (!$return) {
foreach ($sort as $k=>$o){
$condition = strtolower($o) == 'desc'?'>=':'<=';
//检查交换位置后,判断之前的大小关系结果是否依然成立,不再判断当前key,只比较$key之前的排序是否正确
if($k == $key){
break;
}
if(!eval("return {$array[$i+1][$k]} {$condition} {$array[$i][$k]};")){
//检查交换位置后,不再满足条件,不交换位置,继续$i+1的循环
continue 2;
}
}
//检查交换位置后,判断之前的大小关系结果是否依然成立,不再判断当前key=>条件依然成立,互换位置
$temp = $array[$i+1];
$array[$i+1] = $array[$i];
$array[$i] = $temp;
$i = -1;//控制循环指针,下次最外层依旧从0开始
break;
}
}
}
return $array;
}
不使用eval
/**
* 二维数组多字段排序
* @param array $array
* @param array $sort:['a'=>'desc','b'=>'asc','d'=>'desc']
* @return array
*/
function sortArrByManyField(array $array, $sort = [])
{
if (!$sort) {
return $array;
}
$array = array_values($array);
for ($i=0; $i < count($array); ++$i) {
foreach ($sort as $key=>$order){
if(!isset($array[$i+1])){
break 2;
}
if(strtolower($order) == 'desc'){
$bool = $array[$i][$key] >= $array[$i+1][$key];
}else{
$bool = $array[$i][$key] <= $array[$i+1][$key];
}
if (!$bool) {
foreach ($sort as $k=>$o){
//检查交换位置后,判断之前的大小关系结果是否依然成立,不再判断当前key,只比较$key之前的排序是否正确
if($k == $key){
break;
}
if(strtolower($o) == 'desc'){
$bool = $array[$i+1][$k] >= $array[$i][$k];
}else{
$bool = $array[$i+1][$k] <= $array[$i][$k];
}
if(!$bool){
//检查交换位置后,不再满足条件,不交换位置,继续$i+1的循环
continue 2;
}
}
//检查交换位置后,判断之前的大小关系结果是否依然成立,不再判断当前key=>条件依然成立,互换位置
$temp = $array[$i+1];
$array[$i+1] = $array[$i];
$array[$i] = $temp;
$i = -1;//控制循环指针,下次最外层依旧从0开始
break;
}
}
}
return $array;
}