PHP - 按父级和id排序数组(高级)

时间:2016-12-31 16:25:40

标签: php arrays sorting

我有一个数组数组 - 每个数组都有自己的id和父id值。 我想对它进行排序,以便每个孩子都应该在它的父母之下。 让我告诉你我的代码:

  1. 给定数组:

    $arr = array(array('id' => 15, 'parent' => 12), 
    array('id' => 10, 'parent' => 12), 
    array('id' => 12, 'parent' => 12), 
    array('id' => 17, 'parent' => 12), 
    array('id' => 21, 'parent' => 15), 
    array('id' => 13, 'parent' => 15), 
    array('id' => 15, 'parent' => 15), 
    array('id' => 25, 'parent' => 15), 
    array('id' => 7, 'parent' => 7), 
    array('id' => 18, 'parent' => 7), 
    array('id' => 4, 'parent' => 7), 
    array('id' => 1, 'parent' => 3), 
    array('id' => 5, 'parent' => 5), 
    array('id' => 2, 'parent' => 7));
    
  2. 输出应该如何(父母的asc,每个孩子也都在提升 - 总是在父母之下(父母总是在第一位):

          0 =>
              'id' => int 1
              'parent' => int 3
          1 =>
              'id' => int 5
              'parent' => int 5
          2 =>
              'id' => int 7
              'parent' => int 7
          3 =>
              'id' => int 2
              'parent' => int 7
          4 =>
              'id' => int 4
              'parent' => int 7
          5 =>
              'id' => int 18
              'parent' => int 7
          6 =>
              'id' => int 12
              'parent' => int 12
          7 =>
              'id' => int 10
              'parent' => int 12
          8 =>
              'id' => int 15
              'parent' => int 12
          9 =>
              'id' => int 17
              'parent' => int 12
          10 =>
              'id' => int 15
              'parent' => int 15
          11 =>
              'id' => int 13
              'parent' => int 15
          12 =>
              'id' => int 21
              'parent' => int 15
          13 =>
              'id' => int 25
              'parent' => int 15
    
  3. 问题: 我想知道实现这个目标的最简单方法是什么?我已设法做到这一点,但我不能停止这种感觉,有一种方法可以更快,更优化的方式做到这一点..

  4. 这是我的代码:

    function groupByParent ($array)
    {
        $groups = array();
        foreach ($array as $a) {
            $groups[$a['parent']][] = $a;
        }
        return $groups;
    }
    function insideSort ($array)
    {
        foreach ($array as $k => $v) {
            usort($array[$k], function($a, $b){
               return $a['id'] == $b['parent'] ? -1 : 1;
            });
            $f = array_shift($array[$k]);
            sort($array[$k]);
            array_unshift($array[$k], $f);
        }
        return $array;
    }
    function finalSort($array)
    {
        $final = array();
        foreach ($array as $a) {
            $final = array_merge($final, $a);
        }
        return $final;
    }
    
    $grr = groupByParent($arr);
    $irr = insideSort($grr);
    ksort($irr);
    $res = finalSort($irr);
    
  5. 有没有更简单的方法来实现它?

  6. 干杯

2 个答案:

答案 0 :(得分:2)

您可以将array_multisortarray_column一起使用:

array_multisort(
    array_column($arr, 'parent'),
    array_column($arr, 'id'),
    $arr
);

这是working demo

我想这是最简单,最正确的方法,因为为这种情况创建了array_multisort

答案 1 :(得分:0)

您希望查看usort以使用用户定义的比较函数按值对数组进行排序

<?php
$arr = [
    ['id' => 15, 'parent' => 12],
    ['id' => 10, 'parent' => 12],
    ['id' => 12, 'parent' => 12],
    ['id' => 17, 'parent' => 12],
    ['id' => 21, 'parent' => 15],
    ['id' => 13, 'parent' => 15],
    ['id' => 15, 'parent' => 15],
    ['id' => 25, 'parent' => 15],
    ['id' => 7, 'parent' => 7],
    ['id' => 18, 'parent' => 7],
    ['id' => 4, 'parent' => 7],
    ['id' => 1, 'parent' => 3],
    ['id' => 5, 'parent' => 5],
    ['id' => 2, 'parent' => 7],
];
usort(
    $arr,
    function ($a, $b) {
        if ($a['parent'] == $b['parent']) {
            if ($a['id'] == $b['id']) {
                return 0;
            }

            return ($a['id'] < $b['id']) ? -1 : 1;
        }

        return ($a['parent'] < $b['parent']) ? -1 : 1;
    }
);
var_dump($arr);

此输出

array(14) {
  [11]=>
  array(2) {
    ["id"]=>
    int(1)
    ["parent"]=>
    int(3)
  }
  [12]=>
  array(2) {
    ["id"]=>
    int(5)
    ["parent"]=>
    int(5)
  }
  [13]=>
  array(2) {
    ["id"]=>
    int(2)
    ["parent"]=>
    int(7)
  }
  [10]=>
  array(2) {
    ["id"]=>
    int(4)
    ["parent"]=>
    int(7)
  }
  [8]=>
  array(2) {
    ["id"]=>
    int(7)
    ["parent"]=>
    int(7)
  }
  [9]=>
  array(2) {
    ["id"]=>
    int(18)
    ["parent"]=>
    int(7)
  }
  [1]=>
  array(2) {
    ["id"]=>
    int(10)
    ["parent"]=>
    int(12)
  }
  [2]=>
  array(2) {
    ["id"]=>
    int(12)
    ["parent"]=>
    int(12)
  }
  [0]=>
  array(2) {
    ["id"]=>
    int(15)
    ["parent"]=>
    int(12)
  }
  [3]=>
  array(2) {
    ["id"]=>
    int(17)
    ["parent"]=>
    int(12)
  }
  [5]=>
  array(2) {
    ["id"]=>
    int(13)
    ["parent"]=>
    int(15)
  }
  [6]=>
  array(2) {
    ["id"]=>
    int(15)
    ["parent"]=>
    int(15)
  }
  [4]=>
  array(2) {
    ["id"]=>
    int(21)
    ["parent"]=>
    int(15)
  }
  [7]=>
  array(2) {
    ["id"]=>
    int(25)
    ["parent"]=>
    int(15)
  }
}
➜  promote-api git:(develop) ✗ php test.php
array(14) {
  [0]=>
  array(2) {
    ["id"]=>
    int(1)
    ["parent"]=>
    int(3)
  }
  [1]=>
  array(2) {
    ["id"]=>
    int(5)
    ["parent"]=>
    int(5)
  }
  [2]=>
  array(2) {
    ["id"]=>
    int(2)
    ["parent"]=>
    int(7)
  }
  [3]=>
  array(2) {
    ["id"]=>
    int(4)
    ["parent"]=>
    int(7)
  }
  [4]=>
  array(2) {
    ["id"]=>
    int(7)
    ["parent"]=>
    int(7)
  }
  [5]=>
  array(2) {
    ["id"]=>
    int(18)
    ["parent"]=>
    int(7)
  }
  [6]=>
  array(2) {
    ["id"]=>
    int(10)
    ["parent"]=>
    int(12)
  }
  [7]=>
  array(2) {
    ["id"]=>
    int(12)
    ["parent"]=>
    int(12)
  }
  [8]=>
  array(2) {
    ["id"]=>
    int(15)
    ["parent"]=>
    int(12)
  }
  [9]=>
  array(2) {
    ["id"]=>
    int(17)
    ["parent"]=>
    int(12)
  }
  [10]=>
  array(2) {
    ["id"]=>
    int(13)
    ["parent"]=>
    int(15)
  }
  [11]=>
  array(2) {
    ["id"]=>
    int(15)
    ["parent"]=>
    int(15)
  }
  [12]=>
  array(2) {
    ["id"]=>
    int(21)
    ["parent"]=>
    int(15)
  }
  [13]=>
  array(2) {
    ["id"]=>
    int(25)
    ["parent"]=>
    int(15)
  }
}