2017-01-01 9 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)); 

出力は次のようになりますどのように(両親によって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 

質問:これを達成する最も簡単な解決策は何でしょうか?

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を持つノードの先頭に配列の先頭を追加します。

ビッグ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 

結果はコードの上下に微小時間(true)を使用して発見した開始時刻から終了時刻を差し引きました。上記のコード内の1つのような小さな配列を使用しているとき、それは特に、もう少し効率的だよう

結論

は、だから私は、提供されたコードがneccessarilyあなたが望むものを達成するための簡単な方法ではありません、しかし、それは見えます。

私は大きなアレイで実行時間をテストしていないので、解決策を選択する前にアドバイスをお願いします。

「適切に表示する」部分(私のコードの48-50行目)を取り除き、最初から最後まで適切にデータを格納する方法を見つけ出すことができれば、実行時間はかなり改善されます。

幸運と幸せな新年!