2009-12-03 8 views
6

Questa è probabilmente una domanda semplice, ma come si fa a scorrere un array, facendo qualcosa a ciascuno, fino all'ultimo e facendo qualcosa di diverso?Come utilizzare un ciclo foreach, ma fare qualcosa di diverso sull'ultima iterazione?

Ho una matrice di nomi. Voglio produrre l'elenco di nomi separati da virgole.

Joe, Bob, Foobar

Non voglio una virgola alla fine del cognome nella matrice, né se v'è un solo valore nella matrice (o nessuno!) .

Aggiornamento: Non riesco a utilizzare implode() perché ho una matrice di oggetti Modello utente in cui ottengo il nome da ciascun oggetto.

$users = array(); 
$users[] = new User(); 

foreach ($users as $user) { 
    echo $user->name; 
    echo ', '; 
} 

Come posso ottenere questo e utilizzare ancora questi oggetti?

Aggiornamento: Mi sono preoccupato troppo di quante righe di codice stavo inserendo nel mio script di visualizzazione, quindi ho deciso di creare un helper di visualizzazione. Ecco quello che ho finito con:

$array = array(); 
foreach($users as $user) { 
    $array[] = $user->name; 
} 
$names = implode(', ', $array); 
+0

@Andrew, ho aggiornato la mia domanda con una risposta per l'aggiornamento. –

risposta

15

Uso implode:

$names = array('Joe', 'Bob', 'Foobar'); 
echo implode(', ', $names); # prints: Joe, Bob, Foobar 

per chiarire, se v'è un solo oggetto nella matrice, la Il separatore ', ' non verrà utilizzato e verrà restituita una stringa contenente il singolo elemento.

EDIT: Se si dispone di un array di oggetti, e si voleva fare in modo diverso da un ciclo for con i test, si potrebbe fare questo:

function get_name($u){ return $u->name; }; 
echo implode(', ', array_map('get_name', $users)); # prints: Joe, Bob, Foobar 
+0

grazie per la tua risposta, sfortunatamente non posso usare implode() perché la matrice contiene oggetti. C'è un modo diverso per ottenere la stessa cosa? – Andrew

+2

In PHP 5.3+ non è necessario dichiarare una funzione, basta farlo in modo anonimo: implode (',', array_map (function ($ user) {return $ user-> name;}, $ users) –

+0

È esso è male che ho scritto php per anni e non ho mai pensato a questo? –

6
$array = array('joe', 'bob', 'Foobar'); 
$comma_separated = join(",", $array); 

uscita:

joe,bob,Foobar

+0

apparentemente join è un alias per implode :) –

+0

In realtà preferisco l'uso di join perché non confonde quelli provenienti da uno sfondo java/perl. – karim79

+0

Lo so! Purtroppo, 'split' non è un alias per' explode'. Quindi in PHP uso solo 'explode' e' implode' come zoppo quanto i nomi sono :) –

1

implode(', ', $array_of_names)

1

psuedocode ....

integer sigh=container.getsize(); 
sigh--; 
integer gosh=0; 
foreach element in container 
{ 
    if(gosh!=sigh) 
    dosomething(); 
    else 
    doLastElementStuff(); 
    gosh++; 
} 

guardando tutte le altre risposte, sembra PHP ha ottenuto molto più sintattica S dall'ultima volta che ho scritto qualcosa al suo interno: D

+0

Ti darei un +1 per leggere il titolo, ma dovrei dare un -1 per non leggere la domanda :) –

+0

Le domande sono state modificate mentre ho scritto la risposta:/ –

+0

Ah, ha senso. Devo esserci imbattuto in esso subito dopo la modifica. –

3

A volte potresti non voler usare implode. Il trucco è quindi quello di utilizzare una variabile ausiliaria per monitorare non l'ultimo, ma la prima volta attraverso il ciclo. vis:

$names = array('Joe', 'Bob', 'Foobar'); 
$first = true; 
$result = ''; 
foreach ($names as $name) 
{ 
    if (!$first) 
     $result .= ', '; 
    else 
     $first = false; 

    $result .= $name; 
} 
+0

Questo mi fa incazzare la testa. –

0

personalmente ho trovato il modo più veloce (se siete in micro ottimizzazione) è:

if(isset($names[1])) { 
    foreach ($names as $name) { 
     $result .= $name . ', '; 
    } 
    $result = substr($result, 0, -2); 
    } else { 
    $result = $names[0]; 
    } 

isset($names[1]) è il modo più veloce (anche se non così chiaro) di verificare la lunghezza del una matrice (o stringa). In questo caso, viene eseguito il controllo di almeno due elementi.

+0

È necessario '-2' anziché' -1' per rimuovere lo spazio __e__ la virgola. –

+0

sorry, fixed, tired:] – raveren

1

vengo attraversavano questo un terreno edificabile istruzioni SQL, ecc

$joiner = " "; 
foreach ($things as $thing) { 
    echo " $joiner $thing \n"; 
    $joiner = ','; 
} 

per qualche motivo è più facile capire la logica se si pensa alla "", 'E' o 'O' come opzione/attributo che precede un elemento. Il problema diventa quindi come sopprimere il "," sulla prima riga.

+0

Molto bello finché lo spazio bianco non è un problema. Ma il concetto è forte e potresti scriverlo diversamente per rimuovere gli spazi bianchi extra. +1 –

0

In realtà trovo più semplice creare un testo delimitato da virgole in modo leggermente diverso. È un po 'più verboso, ma è meno chiamate di funzione.

<?php 
$nameText = ""; 
for ($i = 0; $i < count($nameArray); $i++) { 
if ($i == 0) { 
$nameText = $nameArray[$i]; 
} 
else { 
$nameText .= "," . $nameArray[$i]; 
} 
} 

Si aggiunge la virgola come un prefisso ad ogni nome, tranne dove è il primo elemento se l'array. Mi sono affezionato all'utilizzo di per rispetto a foreach poiché ho un facile accesso all'indice corrente e quindi agli elementi adiacenti di un array. Si potrebbe utilizzare foreach in questo modo:

<?php 
$nameText = ""; 
$nameCounter = 0; 
for ($nameArray as $thisName) { 
if ($nameCounter == 0) { 
$nameText = $thisName; 
$nameCounter++; 
} 
else { 
$nameText .= "," . $thisName; 
} 
} 
+0

Ma 'count' valuta ancora su ogni ciclo, quindi hai ancora una chiamata di funzione per loop. Inoltre, stai introducendo un'istruzione 'if' su ogni loop. –

Problemi correlati