代码之家  ›  专栏  ›  技术社区  ›  Justinus Hermawan

PHP usort树数组

  •  1
  • Justinus Hermawan  · 技术社区  · 7 年前

    我想根据键对结构如下的树层次结构数组进行排序(在本例中: 时间戳 ).

    $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 回复  |  直到 7 年前
        1
  •  1
  •   Barmar    7 年前

    这不管用,因为 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

    推荐文章