php - 按多个字段对多维数组进行排序

标签 php arrays usort

我发现了一些与此相关的问题,但我觉得我这里有一个非常特殊的情况,所以我要问一个新问题。

我需要首先按用户的头衔(数组)然后按姓氏对用户数组进行排序,请考虑以下代码:

<?php
$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']
    ]
];

我想要的顺序是:

<?php
$order = [
    'Senior Manager',
    'Manager',
    'Supervisor'
];

如果有多个经理,他们应该按姓氏排序,因此这种情况下的输出将是:

<?php
$sorted = [
    [
        'lastName' => 'Adams',
        'titles' => ['Manager', 'Senior Manager']
    ],
    [
        'lastName' => 'Davids',
        'titles' => ['Senior Manager']
    ],
    [
        'lastName' => 'Clarks',
        'titles' => ['Manager', 'Supervisor']
    ],
    [
        'lastName' => 'Clarkson',
        'titles' => ['Manager']
    ],
    [
        'lastName' => 'Adams',
        'titles' => ['Supervisor']
    ],
    [
        'lastName' => 'Clarkson',
        'titles' => ['Sales']
    ]
];

我已经尝试过一些类似的方法,但无法让它工作,并且发现调试usort有点困难:

<?php
foreach ($order as $title) {
    usort($users, function ($a, $b) use ($title) {
        # Both have the title
        if (in_array($title, $a['titles']) and in_array($title, $b['titles']) ) {
            # Sort by name
            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;
        }

        # No-one has the title
        return strcmp($a['lastName'], $b['lastName']);
    });
}

最佳答案

问题是数组被一遍又一遍地排序。因此,如果您在 foreach 循环中逐步进行,则项目首先按高级经理头衔排序,然后再次按经理头衔排序,最后再次按主管头衔排序。

所以首先,你必须颠倒你想要的顺序:

$order = array_reverse([
    'Senior Manager',
    'Manager',
    'Supervisor'
]);

如果项目都没有标题,那么您就不想移动它们。因为在您的其他迭代中,您的高级经理可能没有主管头衔,而其他用户也可能没有该头衔,因此他们都不应该改变职位。所以可以将最后的return改为return 0;

最后,您已经颠倒了 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"
    }
  }
}

关于php - 按多个字段对多维数组进行排序,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/58649309/

相关文章:

java - Java 中 Python (.append) 的对应项是什么

PHP usort 不会对类进行排序

php - laravel 从 3 个表中选择所有行

python - 将数组元素从科学记数法转换为python中的十进制记数法

php - 使用 MySQL 为帖子投票/点赞系统

Javascript 数组索引基础

PHP匿名函数作用域问题

php - codeigniter加入2表数据

javascript - 我想在 php 脚本中创建带有联系表单的自动弹出窗口