views:

6670

answers:

7

Is there an easy way to iterate over an associative array of this structure in PHP:

The array $searches has a numbered index, with between 4 and 5 associative parts. So I not only need to iterate over $searches[0] through $searches[n], but also $searches[0]["part0"] through $searches[n]["partn"]. The hard part is that different indexes have different numbers of parts (some might be missing one or two).

Thoughts on doing this in a way that's nice, neat, and understandable?

+2  A: 

You should be able to use a nested foreach statment

from the php manual

/* foreach example 4: multi-dimensional arrays */
$a = array();
$a[0][0] = "a";
$a[0][1] = "b";
$a[1][0] = "y";
$a[1][1] = "z";

foreach ($a as $v1) {
    foreach ($v1 as $v2) {
        echo "$v2\n";
    }
}
Re0sless
A: 

Can you just loop over all of the "part[n]" items and use isset to see if they actually exist or not?

Mark Biek
+11  A: 

I'm not sure I understand the problem. Do you know the foreach loop? Why not simply nest it?

foreach ($array as $i => $values) {
    print "$i {\n";
    foreach ($values as $key => $value) {
        print "    $key => $value\n";
    }
    print "}\n";
}
Konrad Rudolph
is $i and $values a copy temp variable from the associative array or do they refer to the actual array reference?
MMAMail.com
Konrad Rudolph
A: 

I'm really not sure what you mean here - surely a pair of foreach loops does what you need?

foreach($array as $id => $assoc)
{
    foreach($assoc as $part => $data)
    {
     // code
    }
}

Or do you need something recursive? I'd be able to help more with example data and a context in how you want the data returned.

Ross
+1  A: 

Looks like a good place for a recursive function, esp. if you'll have more than two levels of depth.

function doSomething(&$complex_array)
{
    foreach ($complex_array as $n => $v)
    {
        if (is_array($v))
            doSomething($v);
        else
            do whatever you want to do with a single node
    }
}
Milan Babuškov
A: 

I need help with what I think is close to the same issue as discussed in this thread. I have tried the approaches here and none solve my problem. But I consider myself a high beginner with php, so it may be I don't understand the issue.

I am trying to create a web page showing in descending order the albums I have listened to according to the last.fm database which is scrobbled (great word) up to last.fm from my Sonos system. The scrobble works. I can get the information down using a php lastfmapi class. I can print portions of the array for all items in the array.

I am using php and Smarty for the display template. This really may be a Smarty issue.

Here are the first two items in the array as shown by print_r:

Array ( [0] => Array ( [name] => American Angels: Songs of Hope, Redemption, & Glory [playcount] => 224 [mbid] => [url] => http://www.last.fm/music/Anonymous+4/American%2BAngels%253A%2BSongs%2Bof%2BHope%252C%2BRedemption%252C%2B%2526%2BGlory [artist] => Array ( [name] => Anonymous 4 [mbid] => bdbd99ab-3f4b-4028-9306-cd71d8695fbc [url] => http://www.last.fm/music/Anonymous+4 )

        [images] => Array
            (
                [small] => http://cdn.last.fm/depth/catalogue/noimage/cover_med.gif
                [medium] => http://cdn.last.fm/depth/catalogue/noimage/cover_med.gif
                [large] => http://cdn.last.fm/depth/catalogue/noimage/cover_med.gif
            )

    )

[1] => Array
    (
        [name] => Reflections of Spain: Spanish Favorites for Guitar
        [playcount] => 83
        [mbid] => 
        [url] => http://www.last.fm/music/David+Russell/Reflections+of+Spain%3A+Spanish+Favorites+for+Guitar
        [artist] => Array
            (
                [name] => David Russell
                [mbid] => 18704857-e7d9-4923-8cb1-fea1aea51111
                [url] => http://www.last.fm/music/David+Russell
            )

        [images] => Array
            (
                [small] => http://cdn.last.fm/depth/catalogue/noimage/cover_med.gif
                [medium] => http://cdn.last.fm/depth/catalogue/noimage/cover_med.gif
                [large] => http://cdn.last.fm/depth/catalogue/noimage/cover_med.gif
            )

    )

Here is what I think is the relevant part of the test.php file and the Smarty template:

$i = 0; foreach ($albums as $v1) { $myalbumarray[$i] = (array($v1[images][large],$v1[url],$v1[name], $v1[artist][name], $v1[playcount]));

$i++; }

This function returns the $myalbumarray and it is assigned to $albums which is then assigned to Smarty with:

$smarty->assign('Album', $albums);

Now we show the page!

$smarty->display('Album.tpl');

The Smarty template file (.tpl) in relevant part says:

{foreach name=outer item=album from=$Album}


{foreach key=key item=item from=$album} {$item}
{/foreach} {/foreach}

which outputs:

http://cdn.last.fm/depth/catalogue/noimage/cover_med.gif http://www.last.fm/music/Anonymous+4/American%2BAngels%253A%2BSongs%2Bof%2BHope%252C%2BRedemption%252C%2B%2526%2BGlory American Angels: Songs of Hope, Redemption, & Glory Anonymous 4 224

http://cdn.last.fm/depth/catalogue/noimage/cover_med.gif http://www.last.fm/music/David+Russell/Reflections+of+Spain%3A+Spanish+Favorites+for+Guitar Reflections of Spain: Spanish Favorites for Guitar David Russell 83

What I want to do is format in Smarty so that it looks something like the most recently played track at http://billhogsett.com/musictest.php. I would plan to output in the large center .div where the text is now.

Hope this is enough--and not too much--information. This thread was as good as I found trying to solve the issue.

Bill Hogsett

+1  A: 

I know it's question necromancy, but iterating over Multidimensional arrays is easy with Spl Iterators

$iterator = new RecursiveIteratorIterator(new RecursiveArrayIterator($array));

foreach($iterator as $key=>$value) {
    echo $key.' -- '.$value.'<br />';
}

See

Gordon