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()中完成吗?