Tell me more ×
Stack Overflow is a question and answer site for professional and enthusiast programmers. It's 100% free, no registration required.

a MYSQL Query is getting me this array of objects (shortened a bit):

Array
 (
    [0] => stdClass Object
        (
            [parentTitle] => Winner 2009
            [catTitle] => Max Muster
            [title] => drm202
        )

    [1] => stdClass Object
        (
            [parentTitle] => Winner 2009
            [catTitle] => Max Muster
            [title] => drm202
        )

    [2] => stdClass Object
        (
            [parentTitle] => Winner 2011
            [catTitle] => Josh Frank
            [title] => A bird in the cage
        )

    [3] => stdClass Object
        (
            [parentTitle] => Winner 2011
            [catTitle] => Josh Frank
            [title] => cue & repeat
        )
    ...
)

How is it possible to build an unordered Html List out of this array which looks like this:

<ul id="content">

    <li>Winner 2009
       <ul>
          <li>Max Muster
             <ul>
                  <li>drm202</li> 
             </ul>
          </li>
       </ul>
   </li>

    <li>Winner 2011
       <ul>
          <li>Josh Frank
             <ul>
                  <li>A bird in the cage</li> 
                  <li>cue & repeat</li> 
             </ul>
          </li>
       </ul>
   </li>

</ul>

The first two objects are the same, thus in the ul the person + title should only be listed once under parent winner 2009. The winner from 2011 has two winner projects thus these two different projects should be listed under him.

My approach was to have a foreach loop which fills an array

foreach ($results as $object) { 

    // fill array
    $array[] = "</ul><ul><li><h2> " . $object->parentTitle . "</h2>\n</li>";
    $array[] = "<li><h5>" . $object->catTitle . "</h5></li>\n";
    $array[] = "<li> - " . $object->title . "</li>\n";

}

and kick out the doubles

$array = array_unique($array);

this way seems to be extremly unhandy and wrong.

thanks for any help,

tony

share|improve this question
Are you not using SELECT DISTINCT parentTitle, catTitle, title? – Jack Apr 1 at 8:48

1 Answer

up vote 0 down vote accepted

You can make use of array_walk:

$source=json_decode('[{"parentTitle":"Winner 2009","catTitle":"Mas Muster","title":"drm202"},{"parentTitle":"Winner 2009","catTitle":"Mas Muster","title":"drm202"},{"parentTitle":"Winner 2011","catTitle":"Josh Frank","title":"A bird in the cage"},{"parentTitle":"Winner 2011","catTitle":"Josh Frank","title":"cue & repeat"}]');
$result=array();
array_walk($source,function($v,$i)use(&$result){
    if(!isset($result[$v->parentTitle])) $result[$v->parentTitle]=array();
    if(!isset($result[$v->parentTitle][$v->catTitle])) $result[$v->parentTitle][$v->catTitle]=array();
    if(!in_array($v->title,$result[$v->parentTitle][$v->catTitle])) $result[$v->parentTitle][$v->catTitle][]=$v->title;
});
print_r($result); // just to debug
echo "<ul>";
foreach($result as $key=>$sub){
    echo "<li>".htmlentities($key,ENT_COMPAT,"UTF-8");
    echo "<ul>";
    foreach($sub as $k=>$s){
        echo "<li>".htmlentities($k,ENT_COMPAT,"UTF-8");
        echo "<ul>";
        foreach($s as $i=>$v){
            echo "<li>".htmlentities($v,ENT_COMPAT,"UTF-8")."</li>";
        }
        echo "</ul></li>";
    }
    echo "</ul></li>";
}
echo "</ul>";

Live demo

The print_r output:

Array
(
    [Winner 2009] => Array
        (
            [Mas Muster] => Array
                (
                    [0] => drm202
                )

        )

    [Winner 2011] => Array
        (
            [Josh Frank] => Array
                (
                    [0] => A bird in the cage
                    [1] => cue & repeat
                )

        )

)

The HTML output (not indented):

<ul><li>Winner 2009
<ul><li>Mas Muster
<ul><li>drm202</li>
</ul>
</li></ul>
</li><li>Winner 2011
<ul><li>Josh Frank
<ul><li>A bird in the cage</li>
<li>cue &amp; repeat</li>
</ul>
</li></ul>
</li></ul>

If you want to go further fancy, you can change the foreach clause into another array_walk or array_reduce or something like that.

share|improve this answer
Passerby! Great! Thanks a lot for this really extensive and helpful answer. – t Book Apr 1 at 9:00
Hi Passerby, despite of reading the manual I am having problems to understand the array_walk. Maybe you can help me out again and extend your code a bit. Let´s say I have 3 more values in each array object (id,alias,catalias) which i´d like to access within the inner project list f.e. <li><a="$id/$alias/$catalias">A bird in the cage</a></li>. I´ve changed your fiddle a bit to illustrate what is meant. 3v4l.org/LU8e2 – t Book Apr 4 at 14:11
@tBook Like this: 3v4l.org/FKcM4#v530 – Passerby Apr 5 at 3:08
Hi Passerby, exactly! thanks a million. I learned a lot from your answer. cheers, tBook – t Book Apr 5 at 7:24

Your Answer

 
discard

By posting your answer, you agree to the privacy policy and terms of service.

Not the answer you're looking for? Browse other questions tagged or ask your own question.