2017-01-01 46 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行),而是從頭到尾正確存儲數據,執行時間會得到很大改善。

祝你好運,新年快樂!