Php 按多个字段对多维数组排序
我发现了一些关于这方面的问题,但我觉得我有一个非常特殊的情况,所以我要问一个新的问题 我需要先排序他们的数组(标题),然后按姓氏,考虑下面的代码:Php 按多个字段对多维数组排序,php,arrays,usort,Php,Arrays,Usort,我发现了一些关于这方面的问题,但我觉得我有一个非常特殊的情况,所以我要问一个新的问题 我需要先排序他们的数组(标题),然后按姓氏,考虑下面的代码: 问题是数组被一次又一次地排序。因此,如果您在foreach循环中一步一步地进行,项目首先按高级经理标题排序,然后再按经理标题排序,最后再按主管标题排序 因此,首先,你必须颠倒你想要的顺序: $order = array_reverse([ 'Senior Manager', 'Manager', 'Supervisor' ])
问题是数组被一次又一次地排序。因此,如果您在foreach循环中一步一步地进行,项目首先按高级经理标题排序,然后再按经理标题排序,最后再按主管标题排序
因此,首先,你必须颠倒你想要的顺序:
$order = array_reverse([
'Senior Manager',
'Manager',
'Supervisor'
]);
如果没有标题,您就不想移动项目。因为在您的其他迭代中,您的高级经理可能没有主管头衔,而其他用户也可能没有该头衔,因此他们两人都不应该改变职位。因此,您可以将最后一次返回更改为return0代码>
最后,您已经反转了1
和-1
的返回,因此您只需切换它们
最后,最终代码如下所示:
$users = [
[
'lastName' => 'Clarks',
'titles' => ['Manager', 'Supervisor']
],
[
'lastName' => 'Clarkson',
'titles' => ['Sales']
],
[
'lastName' => 'Adams',
'titles' => ['Supervisor']
],
[
'lastName' => 'Adams',
'titles' => ['Manager', 'Senior Manager']
],
[
'lastName' => 'Clarkson',
'titles' => ['Manager']
],
[
'lastName' => 'Davids',
'titles' => ['Senior Manager']
]
];
$order = array_reverse([
'Senior Manager',
'Manager',
'Supervisor'
]);
foreach ($order as $title) {
usort($users, function ($a, $b) use ($title) {
if (in_array($title, $a['titles']) && in_array($title, $b['titles'])) {
return strcmp($a['lastName'], $b['lastName']);
}
# A has the title
elseif (in_array($title, $a['titles'])) {
return -1;
}
# B has the title
elseif (in_array($title, $b['titles'])) {
return 1;
}
return 0;
});
}
其结果是:
array(6) {
[0]=>
array(2) {
["lastName"]=>
string(5) "Adams"
["titles"]=>
array(2) {
[0]=>
string(7) "Manager"
[1]=>
string(14) "Senior Manager"
}
}
[1]=>
array(2) {
["lastName"]=>
string(6) "Davids"
["titles"]=>
array(1) {
[0]=>
string(14) "Senior Manager"
}
}
[2]=>
array(2) {
["lastName"]=>
string(6) "Clarks"
["titles"]=>
array(2) {
[0]=>
string(7) "Manager"
[1]=>
string(10) "Supervisor"
}
}
[3]=>
array(2) {
["lastName"]=>
string(8) "Clarkson"
["titles"]=>
array(1) {
[0]=>
string(7) "Manager"
}
}
[4]=>
array(2) {
["lastName"]=>
string(5) "Adams"
["titles"]=>
array(1) {
[0]=>
string(10) "Supervisor"
}
}
[5]=>
array(2) {
["lastName"]=>
string(8) "Clarkson"
["titles"]=>
array(1) {
[0]=>
string(5) "Sales"
}
}
}
您需要的是根据$order
中标题的最低索引对用户进行排序。您可以使用array\u search
在$order
中查找每个标题的索引,并使用min
查找最低编号。如果它们相同,请返回到strcmp
usort($users,function($a,$b)use($order){
$minAPos=min(数组\映射(函数($title)使用($order){
$pos=数组搜索($title,$order);
返回$pos==false?sizeof($order):$pos;
},$a[“头衔]);
$minBPos=min(数组映射(函数($title)使用($order){
$pos=数组搜索($title,$order);
返回$pos==false?sizeof($order):$pos;
},$b[“头衔]);
如果($minAPos===$minBPos){
返回strcmp($a['lastName'],$b['lastName']);
}否则{
返回$minAPos$minBPos;
}
});
当你说你想让他们在$order
值中,我想你是指“高级经理”然后是“经理”等等,如果有一个是“高级经理”和“经理”,另一个是“高级经理”和“主管”?@NigelRen我想只要高级经理先来就好了。谢谢!是的,看看我自己的代码,我明白为什么数组需要反转。我会把它归咎于睡眠不足:p1/-1只是我的缺点:P但是在这种情况下,没有出现在某个标题中的用户还会按名称排序吗?或者在运行这种分类之前我应该这样做吗?有没有办法在一次usort调用中完成所有操作?@powerbucket用户(没有标题)将位于数组的末尾,如您所见。这些数据是从数据库检索的吗?如果是这样的话,你可以在数据库级别进行排序。从一个我无法控制的API,但我想我会在这个API之前进行一个aname排序?事实上,不,我无法让它工作。如果我只做名称排序,它工作得很好,如果我只做标题排序,它工作得很好(有你的更新),但是如果我在标题排序之前做名称排序,名称排序没有效果。这一切能在一个usort()中完成吗?