【问题标题】:PHP Sorting Multidimensional array by number of occurrences of values in a keyPHP按键中值的出现次数对多维数组进行排序
【发布时间】:2016-07-23 01:15:32
【问题描述】:

我正在尝试首先按 Rank 中的数量排序,如果数量相等,则按 Rank 进行数字排序。

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

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

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

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

例子:

大批 ( [0] => 数组 ( [排名] => 7 [西装] => 红心 ) [1] => 数组 ( [排名] => 3 [西装] => 红心 ) [2] => 数组 ( [排名] => 6 [西装] => 黑桃 ) [3] => 数组 ( [排名] => 10 [西装] => 黑桃 ) [4] => 数组 ( [排名] => 3 [西装] => 黑桃 ) [5] => 数组 ( [排名] => 6 [西装] => 红心 ) [6] => 数组 ( [排名] => 2 [西装] => 俱乐部 ) )

根据我的算法

大批 ( [0] => 数组 ( [排名] => 6 [西装] => 红心 ) [1] => 数组 ( [排名] => 6 [西装] => 黑桃 ) [2] => 数组 ( [排名] => 3 [西装] => 黑桃 ) [3] => 数组 ( [排名] => 3 [西装] => 红心 ) [4] => 数组 ( [排名] => 10 [西装] => 黑桃 ) [5] => 数组 ( [排名] => 7 [西装] => 红心 ) [6] => 数组 ( [排名] => 2 [西装] => 俱乐部 ) )

【问题讨论】:

    标签: php arrays sorting usort


    【解决方案1】:

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

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

    spaceship 运算符使比较逻辑非常清晰易读。将对应的值写入运算符两侧的数组中,以声明排序条件的顺序。左边写$b值,右边写$a值,实现DESC顺序。

    代码:(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 内的两个数组中即可完成。飞船操作员非常好用且功能强大。

    【讨论】:

      【解决方案2】:

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

      这是一个外观示例:

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

      【讨论】:

      • 谢谢你的回复,我会测试一下,但我不确定你为什么最后按西装排序?
      • 哦,抱歉,我以为您也想这样做。我想出了一个更简单的版本,我会在稍后编辑我的答案。
      • 我认为当前版本更清楚您要完成的工作。
      • 嗯,好像只是按等级组织的。
      • 我忘记从以前的解决方案中删除 count 调用。现在应该没事了。
      猜你喜欢
      • 1970-01-01
      • 2022-01-12
      • 2012-06-15
      • 1970-01-01
      • 1970-01-01
      • 2013-02-06
      • 1970-01-01
      • 1970-01-01
      相关资源
      最近更新 更多