PHP 按键中值的出现次数对多维数组进行排序

PHP Sorting Multidimensional array by number of occurrences of values in a key

我尝试先按排名中的数量排序,如果数量相等,则按排名数字排序。

这听起来可能很复杂,但这是我设想的伪代码

  1. 首先按照Rank中重复值的个数对数组进行排序。
  2. 如果重复值的数量相等,则按排名中的值进行数字排序。

我猜它有点递归,因为第二部分是在所有子数组上执行的。

我一直在尝试使用 usort,但我做不到,所以请查看数组中重复排名值的计数。 Multisort 似乎也不适合。

示例:

Array
(
    [0] => Array
        (
            [Rank] => 7
            [Suit] => Hearts
        )

    [1] => Array
        (
            [Rank] => 3
            [Suit] => Hearts
        )

    [2] => Array
        (
            [Rank] => 6
            [Suit] => Spades
        )

    [3] => Array
        (
            [Rank] => 10
            [Suit] => Spades
        )

    [4] => Array
        (
            [Rank] => 3
            [Suit] => Spades
        )

    [5] => Array
        (
            [Rank] => 6
            [Suit] => Hearts
        )

    [6] => Array
        (
            [Rank] => 2
            [Suit] => Clubs
        )

)

根据我的算法

Array
(

    [0] => Array
        (
            [Rank] => 6
            [Suit] => Hearts
        )

    [1] => Array
        (
            [Rank] => 6
            [Suit] => Spades
        )

    [2] => Array
        (
            [Rank] => 3
            [Suit] => Spades
        )


    [3] => Array
        (
            [Rank] => 3
            [Suit] => Hearts
        )

    [4] => Array
        (
            [Rank] => 10
            [Suit] => Spades
        )

    [5] => Array
        (
            [Rank] => 7
            [Suit] => Hearts
        )

    [6] => Array
        (
            [Rank] => 2
            [Suit] => Clubs
        )

)

我能想到的最简单的解决方案是使用第二个数组,我们将在其中存储每个等级的牌数。然后我们可以将这个数组传递给排序函数,以获得我们想要的结果。

这是一个示例:

$cards = [...];

$ranks = [];

// Count the cards for each rank
foreach ($cards as $card) {
    if (!isset($ranks[$card['Rank']])) {
        $ranks[$card['Rank']] = 0;
    }

    $ranks[$card['Rank']]++;
}

// Sort the cards array
usort($cards, function ($a, $b) use ($ranks) {
    // If the cards count is the same for the rank, compare rank
    if ($ranks[$a['Rank']] == $ranks[$b['Rank']]) {
        return $a['Rank'] - $b['Rank'];
    }

    // Compare the card count for the rank
    return $ranks[$a['Rank']] - $ranks[$b['Rank']];
});

为避免多次执行计数操作,您应该填充排名及其计数的查找数组并将其缓存为变量 ($rankCounts)。使用本机函数是一种直接生成查找数组的简洁方法。

通过 use() 将查找数组传递到 usort() 调用的范围内。

飞船运算符使比较逻辑非常清晰易读。在运算符两边的数组中写入相应的值,声明排序条件的顺序。左边写$b个值,右边写$a个值,实现降序排列

代码:(Demo)

$rankCounts = array_count_values(array_column($array, 'Rank'));

usort(
    $array,
    function($a, $b) use ($rankCounts) {
        return [$rankCounts[$b['Rank']], $b['Rank']] <=> [$rankCounts[$a['Rank']], $a['Rank']];
    }
);

var_export($array);

如果要添加另一个排序规则,只需将其作为元素 [2] 添加到 usort 内部的两个数组中即可。飞船操作符非常好用,功能强大。