上一篇:Vi命令记忆诀窍实践总结(2019-08-11 11:51:06)
文章大纲

php二维数组按指定顺序排序如何实现

2019-08-13 23:20:54

最近在优化公司业务逻辑,挑选服务器ip来建站,为了让服务器ip资源充分利用,需要优先挑选剩余ip数最少的服务器上的ip。


从数据库取出来的二维数组结构大概如下所示:

(为了简化,这里只模拟10条数据)

$dataArr = array(
array('server_id'=>1, 'ip'=>'1.1.1.1', 'user_id'=>66),
array('server_id'=>2, 'ip'=>'1.1.1.2', 'user_id'=>66),
array('server_id'=>3, 'ip'=>'1.1.1.3', 'user_id'=>66),
array('server_id'=>1, 'ip'=>'1.1.1.4', 'user_id'=>66),
array('server_id'=>3, 'ip'=>'1.1.1.5', 'user_id'=>66),
array('server_id'=>2, 'ip'=>'1.1.1.6', 'user_id'=>66),
array('server_id'=>1, 'ip'=>'1.1.1.7', 'user_id'=>66),
array('server_id'=>4, 'ip'=>'1.1.1.8', 'user_id'=>66),
array('server_id'=>3, 'ip'=>'1.1.1.9', 'user_id'=>66),
array('server_id'=>1, 'ip'=>'1.1.1.10', 'user_id'=>66),
);

肉眼可以看出,用户66名下,剩余的ip数目分布是: 

服务器1:4个ip,服务器2:2个ip,服务器3:3个ip,服务器4:1个ip

现在需求就是将上面的二维数组排序,使得ip挑选,依照服务器4、2、3、1的顺序(即优先挑选剩余ip数最少的服务器上的ip)。


实现方式一:

$serverColumn = array_column($dataArr, 'server_id');

//计算每个服务器有多少ip
$serverCount = array_count_values($serverColumn);

//给源二维数组添加remain_ip_count列
foreach($dataArr as &$item){
$item['remain_ip_count'] = $serverCount[$item['server_id']];
}
$countColumn = array_column($dataArr, 'remain_ip_count');
//让二维数组根据remain_ip_count升序排列
array_multisort($countColumn, SORT_ASC, $dataArr);

这样建站取ip时,就依次挑选数组的第一个元素就ok了。


主要思想:把指定的排序转为新列,加到源二维数组上去,然后就可以用array_column和array_multisort来进行排序了


实现方式二:

$serverColumn = array_column($dataArr, 'server_id');

//计算每个服务器有多少ip
$serverCount = array_count_values($serverColumn);
$mainKey = 'server_id';


usort($dataArr, function($a, $b) use ($serverCount, $mainKey){
//$a, $b都是$dataArr的元素,一维数组
if($serverCount[$a[$mainKey]] < $serverCount[$b[$mainKey]] ){
return -1;
}else if( $serverCount[$a[$mainKey]] == $serverCount[$b[$mainKey]]){
return 0;
}else{
return 1;
}
});
var_dump($dataArr);

主要思想:采用usort方法,在usort的第二个参数--回调函数里来实现元素根据自定义顺序排序。

关于usort排序的实现机制,改天有时间去瞅瞅。


在实现上面方法二的时候,遇到了一点小问题,记录一下。

开始用的是显式函数customComp,如下所示:

function customComp($a, $b) use ($serverCount, $mainKey){
if($serverCount[$a[$mainKey]] < $serverCount[$b[$mainKey]] ){
return -1;
}else if( $serverCount[$a[$mainKey]] == $serverCount[$b[$mainKey]]){
return 0;
}else{
return 1;
}
}
usort($dataArr, "customComp");

报如下错误:

Parse error: syntax error, unexpected 'use' (T_USE), expecting '{' in ...

总结:看来这里的use只能搭配匿名函数来使用

另外附带提醒一下,匿名函数,function后要紧跟括号,不要有空格哦。




上一篇:Vi命令记忆诀窍实践总结(2019-08-11 11:51:06)
我要评论
评论列表