按3组密钥对PHP数组进行排序

时间:2012-01-26 21:30:48

标签: php arrays sorting

  

可能重复:
  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,secondary [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
    )

2 个答案:

答案 0 :(得分: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'];
});

答案 1 :(得分:0)

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

  $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的主要顺序   [ID]

它与您想要的输出不对应。辅助意味着当其他键相同时比较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)