PHP usort树数组

时间:2018-08-09 07:11:35

标签: php sorting recursion

我想基于一个键(在此示例中为 timestamp )对具有以下结构的树层次结构数组进行排序。

$topics = array(
  array('name' => 'n1', 'timestamp' => 5000, 'children' => array()),
  array('name' => 'n2', 'timestamp' => 4000, 'children' => array(
    array('name' => 'n3', 'timestamp' => 6000, 'children' => array()),
    array('name' => 'n4', 'timestamp' => 2000, 'children' => array(
      array('name' => 'n5', 'timestamp' => 4000, 'children' => array()),
      array('name' => 'n6', 'timestamp' => 3000, 'children' => array())
    )), 
  )),
  array('name' => 'n7', 'timestamp' => 1000, 'children' => array())
);

我的排序功能:

function sequenceSort(&$a, &$b) {
  if (!empty($a['children'])) {
    usort($a['children'], 'sequenceSort');
  }
  if ($a['timestamp'] == $b['timestamp']) {
    return 0;
  }
  return $a['timestamp'] < $b['timestamp'] ? -1 : 1;
}

usort($topics, 'sequenceSort');
print_a($topics);

在某些级别它会产生正确的输出,而在另一级别则不会,例如:

1000 ✔
4000 ✔
   6000 ✘
   2000 ✘
      4000 ✘
      3000 ✘
5000 ✔

这怎么了?

1 个答案:

答案 0 :(得分:1)

这是行不通的,因为usort()不会通过引用传递数组元素,即使您已使用&声明了参数。我加了:

$a['touched'] = true;

比较功能,当我打印结果时,找不到这些键。

但是,即使它可行,这似乎也是一种非常糟糕的方法,因为它将对孩子进行多次排序-每次将父对象与另一个父对象进行比较时,都必须对子对象进行重新排序。子孙等。

最好编写一个递归函数,该函数对一个级别进行排序,然后遍历子级,依此类推。

function sortRecurse(&$array) {
    usort($array, function($a, $b) {
        return $a['timestamp'] - $b['timestamp'];
    });
    foreach ($array as &$subarray) {
        sortRecurse($subarray['children']);
    }
}

DEMO