【问题标题】:Sort PHP array by group of 3 keys [duplicate]按3个键组对PHP数组进行排序[重复]
【发布时间】:2012-02-19 23:45:57
【问题描述】:

可能重复:
Sort multidimensional array by multiple keys

我正在尝试找到某种方法如何按键名对数组进行排序,但到目前为止没有任何效果。对我来说棘手的部分是通过对 3 个键进行分组来对数组进行排序。我有这个数组。

[0] => Array
    (
        [id] => 8
        [zbo_data] => blah
    )

[1] => Array
    (
        [id] => 6
        [szn_data] => blah
    )

[2] => Array
    (
        [id] => 5
        [gcz_data] => blah
    )

[3] => Array
    (
        [id] => 3
        [gcz_data] => blah
    )

[4] => Array
    (
        [id] => 2
        [zbo_data] => blah
    )

[5] => Array
    (
        [id] => 1
        [szn_data] => blah
    )

我需要按以下顺序按 3 组对其进行排序:szn_data、zbo_data、gcz_data 但我还需要保持 [id] 的顺序(基本上是 szn_data、zbo_data 的主顺序, gcz_data,次要 [id])。有解决办法吗?或者我应该以不同的方式构造数组以便对其进行排序?我试图解决这个问题超过 6 个小时。非常感谢任何帮助。

我想要的输出是:

[0] => Array
    (
        [id] => 6
        [szn_data] => blah
    )

[1] => Array
    (
        [id] => 8
        [zbo_data] => blah
    )

[2] => Array
    (
        [id] => 5
        [gcz_data] => blah
    )

[3] => Array
    (
        [id] => 1
        [szn_data] => blah
    )

[4] => Array
    (
        [id] => 2
        [zbo_data] => blah
    )

[5] => Array
    (
        [id] => 3
        [gcz_data] => blah
    )

【问题讨论】:

    标签: php arrays sorting


    【解决方案1】:

    使用usort 并根据需要实现您的比较功能。例如:

    $result = usort($arr, function($a,$b) {
    
      $keys = array('szn_data', 'zbo_data', 'gcz_data');
      foreach ($keys as $key) {
        // make sure to add here handling of missing keys
        $diff = strcmp($b[$key], $a[$key]);
        if ($diff!=0) {
          return $diff;
        }
      }
    
      return $b['id'] - $a['id'];
    });
    

    【讨论】:

    • 我也试过usort。你能给我一些关于比较功能的提示吗?
    • @user1172238 我刚刚做了,看我的例子
    • 我必须承认我无法弄清楚这个部分//更多比较:(请你这么好心并发布整个功能吗?提前谢谢。
    • @user1172238 好了,应该可以了
    • 由于某种原因无法正常工作。它在 $diff = .. line "Undefined index: szn_data" 上给了我一条通知消息,并且 $result 最后是 "TRUE"。
    【解决方案2】:

    或者像这样,对于一个数组中列出的从最大值到最小值的任何顺序

      $arr = array (
        array(
            'id' => 8,
            'zbo_data' => 'blah'
        ),
        array(
            'id' => 6,
            'szn_data' => 'blah'
        ),
        array(
            'id' => 5,
            'gcz_data' => 'blah'
        ),
        array(
            'id' => 3,
            'gcz_data' => 'blah'
        ),
        array(
            'id' => 2,
            'zbo_data' => 'blah'
        ),
        array(
            'id' => 1,
            'szn_data' => 'blah'
        )
      );
      usort($arr, "my_func");
      var_dump($arr);
    
      function my_func($a, $b)
      {
         $vars = array('szn_data', 'zbo_data', 'gcz_data'); // order of the keys
         $id1 = $a['id']; $id2 = $b['id']; unset($a['id'], $b['id']);
         $index1 = array_search(key($a), $vars);
         $index2 = array_search(key($b), $vars);
         if ($index1 == $index2) {
            if ($id1 == $id2) return 0;
            return ($id1 < $id2) ? 1 : -1;
        }
        return ($index1 < $index2) ? -1 : 1;
      }
    

    ps:

    基本上按 szn_data、zbo_data、gcz_data、secondary 排序 [编号]

    它不符合您想要的输出。次要的意思是在其他key相同时比较id。

    ps:更新 - 这段代码不是很好或完美,但它会给你你需要的东西

      $vars = array('szn_data', 'zbo_data', 'gcz_data');
      $arr = array (
        array(
            'id' => 8,
            'zbo_data' => 'blah'
        ),
        array(
            'id' => 6,
            'szn_data' => 'blah'
        ),
        array(
            'id' => 5,
            'gcz_data' => 'blah'
        ),
        array(
            'id' => 3,
            'gcz_data' => 'blah'
        ),
        array(
            'id' => 2,
            'zbo_data' => 'blah'
        ),
        array(
            'id' => 1,
            'szn_data' => 'blah'
        )
      );
    
      $temp = array();
      $cnt = count($arr);
      foreach($arr as $item)
      {
         foreach($vars as $v)
         {
             if (isset($item[$v])) { $temp[$v][$item['id']] = $item; break; }
         }  
      }
      // sort by id
      foreach($vars as $v)
      {
         krsort($temp[$v]);
         $temp[$v] = array_values($temp[$v]);
      }  
    
      $arr = array(); $i = 0; $j = 0;
      $completed = false;
      do {
         foreach($vars as $v)
         {  
           if ($i++>=$cnt) { $completed = true; break; }           
           if (isset($temp[$v][$j])) $arr[] = $temp[$v][$j];
         }
         $j++; 
      } while (!$completed);
      // output
      var_dump($arr)
    

    【讨论】:

    • 这是排序数组,如:szn_data,szn_data,zbo_data,zbo_data,gcz_data,gcz_data 但它按这 3 个组(szn_data,zbo_data,gcz_szn_data,szn_data,zbo_data,gcz_data,...)
    • @user1172238 阅读更新 - 你告诉这样做。主要订单始终是第一位的,并且仅当主要条件中的项目相等时,才应使用次要订单。 ps:好的,我知道了。让我看看。
    • @Cherry 是的,对订购感到抱歉。它不像我第一次写的那样。
    • @user1172238 检查更新的代码
    • @Cherry 工作就像一个魅力。非常感谢您的帮助!非常感谢!
    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2017-04-02
    • 2023-03-18
    • 1970-01-01
    • 2012-10-04
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多