2017-01-01 275 views
0

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

Given Array: 

$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)); 

如何输出应该像(由家长递增,每个孩子也上升 - 总是在父(母总是像第一次!)):

 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 

问题:我想知道最简单的解决方案是什么?我已经成功地做到这一点,但我不能停止的感觉,有一种方法做,在更快,更优化的方式..

Here is my code: 

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); 

是否有更简单的方法来实现呢?

干杯

+0

是 - 正好!我只是简单地想让这个数组按照升序排序,但子女总是必须在父母之下(父母始终在自己的组中) – user7362902

+0

下面是如何解决问题的另一个示例:http:// pastebin。 com/LPdTNF0Y然而,这是一个混乱的方式,不是一个非常有效的方法。你的解决方案更清洁,运行时间更好,我会坚持下去。 –

回答

1

说明

另一种方式来对数组进行排序,可以通过阵列中的所有元素进行迭代,并找到所有不同的父母,然后存储每个父母所有的兄弟姐妹中发现,除了曾经有与父母相同的id。然后我们按升序对它进行排序,并将与id父节点id相同的节点前置到数组的起始处。

大O符号

的运行时间该算法将有O(n)的最好的情况下,和O的最坏情况(N^2)。

代码

<?php 

$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) 
); 

/* Declare variables */ 
$result = array(); 
$temp = array(); 
$parents = array(); 

/* Get all distinct parents and sort ascending */ 
for ($i = 0; $i < count($arr); $i++) 
    if (!isset($temp[$arr[$i]['parent']])) 
     $temp[$arr[$i]['parent']] = array(); 

ksort($temp); 

/* Find all siblings with same parent */ 
for ($i = 0; $i < count($arr); $i++) 
    if ($arr[$i]['parent'] === $arr[$i]['id']) 
     $parents[] = $arr[$i]['parent']; 
    else 
     $temp[$arr[$i]['parent']][$arr[$i]['id']] = true; 

/* Sort siblings ascending */ 
foreach ($temp as $key => $value) 
    ksort($temp[$key]); 

/* Prepend node where id is same as parent if existing */ 
for ($i = 0; $i < count($parents); $i++) 
    $temp[$parents[$i]] = array($parents[$i] => true) + $temp[$parents[$i]]; 

/* Display properly */ 
foreach ($temp as $key => $value) 
    foreach ($temp[$key] as $subKey => $subValue) 
     $result[] = array('id' => $subKey, 'parent' => $key); 

/* Output */ 
print_r($result); 

?> 

执行时间

Execution time for my code: 
Execution 1: 0.00018095970153809 
Execution 2: 0.00018692016601562 
Execution 3: 0.00022411346435547 
Execution 4: 0.00018596649169922 
Execution 5: 0.00018620491027832 
Execution 6: 0.00018501281738281 
Execution 7: 0.00018501281738281 
Execution 8: 0.00018596649169922 
Execution 9: 0.00018095970153809 
Execution 10: 0.00020003318786621 

Average: 0.00019011497 

Execution time for your code: 
Execution 1: 0.00019311904907227 
Execution 2: 0.0001978874206543 
Execution 3: 0.00019693374633789 
Execution 4: 0.0001981258392334 
Execution 5: 0.0001990795135498 
Execution 6: 0.00028491020202637 
Execution 7: 0.00019598007202148 
Execution 8: 0.00019693374633789 
Execution 9: 0.0001978874206543 
Execution 10: 0.00019717216491699 

Average: 0.00020580291 

结果,使用在顶部和底部代码microtime中(真)并减去从开始时间结束时间找到。

结论

所以我提供的代码是不是neccessarily一个更简单的方式来实现你想要什么,但它看起来像它使用小型阵列像在上面的代码中尤其是当是一个有点更高效。

我还没有测试大阵列的执行时间,并会建议你在选择解决方案之前这样做。

如果你想办法摆脱“正确显示”部分(我的代码中的第48-50行),而是从头到尾正确存储数据,执行时间会得到很大改善。

祝你好运,新年快乐!