简体   繁体   English

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

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

I'm trying to first sort by quantity in Rank and if the quantity is equal then sort numerically by Rank.我试图首先按 Rank 中的数量排序,如果数量相等,则按 Rank 进行数字排序。

It might sound complicated but here is the pseudo-code I envision听起来可能很复杂,但这是我设想的伪代码

  1. First sort arrays by the number of repeated values in Rank.首先按 Rank 中重复值的数量对数组进行排序。
  2. If number of repeated values is equal sort numerically by the value in Rank.如果重复值的数量相等,则按 Rank 中的值进行数字排序。

I guess its kinda recursive seeing as the 2nd part is performed on all sub-arrays.我想它有点递归,因为第二部分是在所有子阵列上执行的。

I've been trying usort but I can't get it so see the count of repeated rank values in the array.我一直在尝试 usort 但我无法得到它所以查看数组中重复排名值的计数。 Multisort doesn't seem to fit either. Multisort 似乎也不适合。

Example:示例:

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
        )

)

According to my algorithm根据我的算法

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
        )

)

The easiest solution I could come up with, is to use a second array in which we'll store the card count for each rank.我能想到的最简单的解决方案是使用第二个数组,我们将在其中存储每个等级的卡数。 We can then pass this array to the sorting function in order to get the result we want.然后我们可以将这个数组传递给排序函数以获得我们想要的结果。

Here's an example of how this would look:下面是一个示例:

$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']];
});

To avoid performing the counting operation multiple times, you should populate the lookup array of ranks and their counts and cache it as a variable ( $rankCounts ).为了避免多次执行计数操作,您应该填充排名及其计数的查找数组并将其缓存为变量( $rankCounts )。 Using native functions is a concise way of directly generating the lookup array.使用原生函数是一种直接生成查找数组的简洁方法。

Pass the lookup array into the scope of the usort() call with use() . use()将查找数组传递到usort()调用的范围内。

The spaceship operator makes the comparison logic very clean and readable. spaceship 运算符使比较逻辑非常清晰易读。 Write corresponding values into the array on either side of the operator to declare the order of the sorting conditions.将相应的值写入运算符两侧的数组中,以声明排序条件的顺序。 Write $b values on the left and $a values on the right to achieve DESC order.$b左侧和值$a上实现DESC顺序正确的价值观。

Code: ( 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);

If you want to add another sorting rule, just add it as element [2] to both arrays inside of usort and you are finished.如果要添加另一个排序规则,只需将其作为元素 [2] 添加到 usort 内部的两个数组中即可。 The spaceship operator is very handy and powerful.飞船操作员非常方便和强大。

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM