2009-05-17 21 views
4

Ich habe ein Array mit Daten aus einer MySQL-Tabelle im geschachtelten Mengenmodell Ich möchte sortiert werden, nicht nur alphabetisch, sondern auch mit den Kindknoten direkt nach dem Elternknoten. Beispiel - Array (vor der Sortierung) sortiert werden:PHP: Ein Array sortieren

Array 
(
    [0] => Array 
     (
      [id] => 1 
      [name] => Kompetenser 
      [parent] => 0 
      [depth] => 0 
     ) 

    [1] => Array 
     (
      [id] => 2 
      [name] => Administration 
      [parent] => 1 
      [depth] => 1 
     ) 

    [2] => Array 
     (
      [id] => 11 
      [name] => Organisation 
      [parent] => 2 
      [depth] => 2 
     ) 

    [3] => Array 
     (
      [id] => 4 
      [name] => Arbetsledning 
      [parent] => 2 
      [depth] => 2 
     ) 

    [4] => Array 
     (
      [id] => 17 
      [name] => Planering 
      [parent] => 2 
      [depth] => 2 
     ) 

    [5] => Array 
     (
      [id] => 9 
      [name] => Hantverke 
      [parent] => 1 
      [depth] => 1 
     ) 

    [6] => Array 
     (
      [id] => 10 
      [name] => Snickeri 
      [parent] => 9 
      [depth] => 2 
     ) 

    [7] => Array 
     (
      [id] => 12 
      [name] => Språk 
      [parent] => 1 
      [depth] => 1 
     ) 

    [8] => Array 
     (
      [id] => 13 
      [name] => Tolk 
      [parent] => 12 
      [depth] => 2 
     ) 

    [9] => Array 
     (
      [id] => 15 
      [name] => Arabiska 
      [parent] => 13 
      [depth] => 3 
     ) 

    [10] => Array 
     (
      [id] => 14 
      [name] => Persiska 
      [parent] => 13 
      [depth] => 3 
     ) 

    [11] => Array 
     (
      [id] => 16 
      [name] => Polska 
      [parent] => 13 
      [depth] => 3 
     ) 

    [12] => Array 
     (
      [id] => 18 
      [name] => Apotekare 
      [parent] => 1 
      [depth] => 1 
     ) 

    [13] => Array 
     (
      [id] => 19 
      [name] => Dotkorand 
      [parent] => 1 
      [depth] => 1 
     ) 

    [14] => Array 
     (
      [id] => 21 
      [name] => Atomfysik 
      [parent] => 19 
      [depth] => 2 
     ) 

    [15] => Array 
     (
      [id] => 20 
      [name] => Fysik 
      [parent] => 19 
      [depth] => 2 
     ) 

    [16] => Array 
     (
      [id] => 22 
      [name] => Ekonom 
      [parent] => 1 
      [depth] => 1 
     ) 

    [17] => Array 
     (
      [id] => 23 
      [name] => Industriell ekonomi 
      [parent] => 22 
      [depth] => 2 
     ) 

    [18] => Array 
     (
      [id] => 24 
      [name] => Filosofi 
      [parent] => 1 
      [depth] => 1 
     ) 

) 

ich das Array auf diese Weise will (nach der Sortierung):

Array 
(
    [0] => Array 
     (
      [id] => 1 
      [name] => Kompetenser 
      [parent] => 0 
      [depth] => 0 
     ) 

    [1] => Array 
     (
      [id] => 2 
      [name] => Administration 
      [parent] => 1 
      [depth] => 1 
     ) 

    [3] => Array 
     (
      [id] => 4 
      [name] => Arbetsledning 
      [parent] => 2 
      [depth] => 2 
     ) 

    [2] => Array 
     (
      [id] => 11 
      [name] => Organisation 
      [parent] => 2 
      [depth] => 2 
     ) 

    [4] => Array 
     (
      [id] => 17 
      [name] => Planering 
      [parent] => 2 
      [depth] => 2 
     ) 

    [12] => Array 
     (
      [id] => 18 
      [name] => Apotekare 
      [parent] => 1 
      [depth] => 1 
     ) 

    [13] => Array 
     (
      [id] => 19 
      [name] => Dotkorand 
      [parent] => 1 
      [depth] => 1 
     ) 

    [14] => Array 
     (
      [id] => 21 
      [name] => Atomfysik 
      [parent] => 19 
      [depth] => 2 
     ) 

    [15] => Array 
     (
      [id] => 20 
      [name] => Fysik 
      [parent] => 19 
      [depth] => 2 
     ) 

    [16] => Array 
     (
      [id] => 22 
      [name] => Ekonom 
      [parent] => 1 
      [depth] => 1 
     ) 

    [17] => Array 
     (
      [id] => 23 
      [name] => Industriell ekonomi 
      [parent] => 22 
      [depth] => 2 
     ) 

    [18] => Array 
     (
      [id] => 24 
      [name] => Filosofi 
      [parent] => 1 
      [depth] => 1 
     ) 

    [5] => Array 
     (
      [id] => 9 
      [name] => Hantverke 
      [parent] => 1 
      [depth] => 1 
     ) 

    [6] => Array 
     (
      [id] => 10 
      [name] => Snickeri 
      [parent] => 9 
      [depth] => 2 
     ) 

    [7] => Array 
     (
      [id] => 12 
      [name] => Språk 
      [parent] => 1 
      [depth] => 1 
     ) 

    [8] => Array 
     (
      [id] => 13 
      [name] => Tolk 
      [parent] => 12 
      [depth] => 2 
     ) 

    [9] => Array 
     (
      [id] => 15 
      [name] => Arabiska 
      [parent] => 13 
      [depth] => 3 
     ) 


    [10] => Array 
     (
      [id] => 14 
      [name] => Persiska 
      [parent] => 13 
      [depth] => 3 
     ) 

    [11] => Array 
     (
      [id] => 16 
      [name] => Polska 
      [parent] => 13 
      [depth] => 3 
     ) 

) 

Wie Sie vielleicht sehen, möchte ich alle Beiträge mit Eltern 2 direkt nach dem Post mit der ID 2, und so weiter.

Jede Hilfe würde sehr geschätzt werden. Vielen Dank im Voraus.

+0

Also was genau Ihre Frage? Wie schreibe ich einen Sortieralgorithmus? Warum hast du überhaupt den Tag für offensichtliche Hausaufgaben verwendet? –

+0

Hinweis: Dies sind Daten aus einem geschachtelten Mengenmodell. Ja, es wäre sehr weit fortgeschritten, wenn Sie diese in einer Abfrage sortieren könnten. Google für "verschachtelte Menge". Und nein, das sind keine Hausaufgaben ... – Ivar

Antwort

0

Problem gelöst - ich machte zwei einfache Funktionen. Ich hoffe, andere Leute könnten auch davon Gebrauch machen:

class data_comp 
{ 
    var $fetched_tree = array(); 

    function tree_fetch($parent = 0) 
    { 
     $query = 'SELECT node.id, node.name, node.parent, (COUNT(parent.name) - 1) AS depth FROM test_competence AS node, test_competence AS parent WHERE node.lft BETWEEN parent.lft AND parent.rgt GROUP BY node.name ORDER BY node.name'; 
     $result = mysql_query($query) or die(mysql_error()); 
     $tree = array(); 

     while($data = mysql_fetch_assoc($result)) 
     { 
      $tree[$data['parent']][$data['id']] = array('name' => $data['name'], 'depth' => $data['depth']); 
     } 

     $this->tree_print($tree, $parent); 
    } 

    function tree_print($tree, $parent) 
    { 
     foreach($tree[$parent] as $id => $value) 
     { 
      $this->fetched_tree[] = array('id' => $id, 'name' => $value['name'], 'depth' => $value['depth']); 

      if(isset($tree[$id]) && is_array($tree[$id])) 
      { 
       $this->tree_print($tree, $id); 
      } 
     } 
    } 
} 

Vielen Dank für Ihre Zeit. Alle Verbesserungen sind mehr als willkommen.

4

Tun Sie das nicht in PHP!

Der MySQL-Server ist specificly, auf der MySQL "ORDER BY" Syntax lesen, abfragen und Sortieren von Daten konzipiert. Wenn Sie dies auf dem MySQL-Server tun, sparen Sie Laufzeit, CPU-Last und Speicherverbrauch.

+1

Ich muss nur erwähnen, dass ich in 5 Jahren mit Websites gearbeitet habe und ich sehr gut über die Order-by-Anweisung in MySQL weiß. Bitte beachten Sie, dass diese Daten aus einer MySQL-Tabelle im Nested-Set-Modell stammen. Lies meinen Kommentar oben. – Ivar

2

Verwenden Sie die Funktion uasort() von php, um Ihre eigene Vergleichsfunktion zu definieren.

Aber die Sortiermöglichkeiten von MySQL wären geeigneter, wenn es in Ihrem Fall möglich ist.

+0

Leider, wie ich in den obigen Posts erwähnt habe, ist es nicht möglich, diese Daten in einem verschachtelten Mengenmodell zu bestellen (soweit ich und Tausende andere Programmierer wissen). Ja, ich habe es mit uasort() versucht, aber ich sortiere sie nur alphabetisch und nicht nach Eltern. Obwohl ich denke, diese Funktion ist der richtige Weg und würde es begrüßen, wenn mir jemand mit einer fortgeschritteneren Version dieser Funktion (oder einer anderen Lösung) helfen könnte. – Ivar

0

Sie möchten es wie in der DB sortieren, mehrschichtig. Ich denke nicht, dass uasort mit diesem Problem helfen kann, weil Sie die Kinder dem Elternteil anhängen möchten.

foreach ($arr as &$val) { 
    $arr2[$val['id']] = &$val; 
} 

ksort($arr2); 

foreach ($arr2 as $id => &$val) { 
    $parent = $val['parent']; 
    if ($parent == 0) { 
     continue; 
    } 
    $arr2[$parent]['children'][$id] = &$val; 
} 

function flattenArrayByChildren($arr) { 
    foreach ($arr as $id => $val) { 
     if (isset($val['children'])) { 
      $temp = flattenArrayByChildren($val['children']); 
      unset($val['children']); 
      $out[$id] = $val; 
      $out = $out + $temp; 
     } else { 
      $out[$id] = $val; 
     } 
    } 
    return $out; 
} 

$arr2 = array(1 => $arr2[1]); 

$out = flattenArrayByChildren($arr2); 

var_dump($out); 

Wenn Sie unbedingt den Schlüssel speichern möchten, können Sie einfach, dass in der ersten foreach, um die $ val hinzufügen und es in die rekursive Funktion flattenArrayByChildren abrufen und als Schlüssel verwenden.

+0

Es ist toll, wenn das funktioniert! Ich werde später testen. Die Leistung ist vielleicht nicht so gut, aber ich werde wahrscheinlich die Daten serialisieren und speichern. – Ivar

+0

Ich habe Ihren Code jetzt getestet. Es sieht so aus, als würde es nur die Kinder von "Administration" (das erste Kind in "Kompetenser") sortieren. Die Kinder in "Komptenser" (alle Kategorien) werden überhaupt nicht sortiert, ebenso wie "Tolk". Es kehrt auch die Reihenfolge von Dotkorand um. – Ivar

+0

Ja, ich habe es nach ID nicht alphabetisch sortiert. Sie müssen es alphabetisch sortieren, bevor Sie sie als Kinder zu einer ID hinzufügen, und dann müssen Sie $ arr anstelle von $ arr2 verwenden. – OIS