2009-08-10 17 views
9

Mam następującą tablicę:Zagnieżdżone foreach()

Array ( 
    [1] => Array ( 
    [spubid] => A00319 
    [sentered_by] => pubs_batchadd.php 
    [sarticle] => Lateral mixing of the waters of the Orinoco, Atabapo 
    [spublication] => Acta Cientifica Venezolana 
    [stags] => acta,confluence,orinoco,rivers,venezuela,waters 
    [authors] => Array ( 
     [1] => Array ( 
     [stype] => Author 
     [iorder] => 1 
     [sfirst] => A 
     [slast] => Andersen) 
     [2] => Array ( 
     [stype] => Author 
     [iorder] => 2 
     [sfirst] => S. 
     [slast] => Johnson) 
     [3] => Array ( 
     [stype] => Author 
     [iorder] => 3 
     [sfirst] => J. 
     [slast] => Doe) 
    ) 
    ) 
) 

Używam zagnieżdżonego foreach(), aby przejść przez elementy w zewnętrznej tablicy, ale jeśli chodzi o plucie na listę autorów jestem wpadanie w problemy. Mianowicie problem wypisywania każdego z wielu (wielu) razy z powodu szalonego zagnieżdżania foreach(). Jakie byłoby lepsze podejście niż zagnieżdżanie pętli foreach() w tym przykładzie?

UPDATE (z roztworem)

Oto pętla zdecydowałem się na, nieco niechlujny (IMHO), ale to działa:

$sauthors = NULL; 
$stitle = NULL; 

foreach($apubs as $apub) 
{ 
    $stitle = $apub['sarticle']; 
    foreach($apub as $svar=>$sval) 
    { 
    if($svar === "authors") 
    { 
     foreach($sval as $apeople) 
     { 
     $sauthors .= $apeople['slast'].", ".$apeople['sfirst']."; "; 
     } 
    } 
    } 
    echo "$sauthors<br />\n$stitle<br />\n"; 
} 
+1

brzmi dobrze, może powinieneś pisać kod w pętli? –

+3

zagnieżdżone pętle nie są domyślnie złe. pozwala zobaczyć jakiś kod. Moje pierwsze dzikie domysły to nadpisanie zmiennej z pętli zewnętrznej w wewnętrznej pętli :) – Rufinus

+1

Wyślij swój kod pętli. Zagnieżdżanie foreach jest w porządku (używanie tablic assoc może pomóc w debugowaniu). – Dirk

Odpowiedz

6

Dlaczego nie zrobić

foreach($apubs as $apub) { 
    $sauthors = ''; 
    $stitle = $apub['sarticle']; 
    foreach($apub['authors'] as $author) { 
    $sauthors .= $author['slast'].", ".$author['sfirst']."; "; 
    } 

    echo "$sauthors<br />\n$stitle<br />\n"; 
} 
2

Jeśli problem jest to, że mają tego samego autora na wielu artykułach, a tym samym uzyskując dane wyjściowe więcej niż jeden raz, najprostszym rozwiązaniem jest zbudowanie tablicy autorów, zamiast wyprowadzania ich od razu.

Gdy masz tablicę wszystkich dotychczas opracowanych autorów, możesz łatwo porównać, czy ten autor już tam jest, czy nie.

1
+0

Podczas gdy ten link może odpowiedzieć na pytanie, lepiej umieścić w nim istotne części odpowiedzi i podać odnośnik. Odpowiedzi dotyczące linków mogą stać się nieprawidłowe, jeśli strona z linkami się zmieni. – edorian

+0

Podczas gdy ten link może odpowiedzieć na pytanie, lepiej umieścić tutaj istotne części odpowiedzi i podać link do odsyłacza. Odpowiedzi dotyczące linków mogą stać się nieprawidłowe, jeśli strona z linkami się zmieni. – edorian

+0

@edorian - Miałem na myśli wszystkie odpowiedzi w tym wątku Stackoverflow. Jeśli kiedykolwiek zerwą te linki, będzie to najbardziej niefortunne, więc bardzo w to wątpię – Bostone

3

tylko dla zabawy. Jeśli naprawdę chcą uniknąć pętli, spróbuj tego:

// Pre PHP 5.3: 

function cb2($e) 
{ 
    return $e['slast'] . ', ' . $e['sfirst']; 
} 

function cb1($e) 
{ 
    $authors = array_map('cb2', $e['authors']); 
    echo implode('; ', $authors) . ":<br />\n" . $e['sarticle'] . "<br />\n"; 
} 

array_walk($data, 'cb1'); 



// PHP 5.3 (untested): 

array_walk($data, function($e) 
{ 
    $authors = array_map(function($e) 
    { 
     return $e['slast'] . ', ' . $e['sfirst']; 
    }, 
    $e['authors']); 

    echo implode('; ', $authors) . ":<br />\n" . $e['sarticle'] . "<br />\n"; 
});