2012-05-31 13 views
11

Possiedo un array di oggetti stdClass e voglio creare un elenco separato da virgole utilizzando un campo specifico di tutti gli oggetti stdClass. La mia serie si presenta così:Come utilizzare implode su una matrice di oggetti stdClass?

$obj1 = stdClass Object ([foo] => 4 [bar] => 8 [foo-bar] => 15); 
$obj1 = stdClass Object ([foo] => 16 [bar] => 23 [foo-bar] => 42); 
$obj1 = stdClass Object ([foo] => 76 [bar] => 79 [foo-bar] => 83); 

$a = array(1=>$obj1 , 2=>$obj2 , 3=>$obj3); 

e voglio implodere su foo di tutti gli oggetti in stdClass tale matrice per creare un elenco separato da virgole. Così il risultato desiderato è:

4,16,76 

Esiste un modo per fare questo con implode (o qualche altra funzione mistero) senza dover mettere questo array di oggetti attraverso un ciclo?

+0

forse se sovraccarichi il metodo toString() dell'oggetto. – clentfort

risposta

25

Si potrebbe utilizzare array_map() e implode() ...

$a = array_map(function($obj) { return $obj->foo; }, 
       array(1=>$obj1 , 2=>$obj2 , 3=>$obj3)); 

$a = implode(", ", $a); 
+0

Questo funziona ed è più pulito di un ciclo, sfortunatamente trovo che un ciclo foreach funzioni meglio. Sto ottenendo risultati simili con array_reduce :(Indovina che mi limiterò a seguire il ciclo foreach. – ubiquibacon

0

Credo che il modo più semplice sarebbe quella di creare un array indicizzato ID e quindi chiamare implodere su array_keys:

$a = array(); 
$a[4] = stdClass Object ([foo] => 4 [bar] => 8 [foo-bar] => 15); 
$a[16] = stdClass Object ([foo] => 16 [bar] => 23 [foo-bar] => 42); 
$a[76] = stdClass Object ([foo] => 76 [bar] => 79 [foo-bar] => 83); 

echo implode(', ', array_keys($a)); 
0

No, il il meglio che puoi fare è iterare, chiamare tostring() sull'oggetto e mettere i risultati in un nuovo array per chiamare implode.

4

Una soluzione molto pulito per questo è la funzione array_reduce(), che riduce un array a un singolo valore:

$str = array_reduce($a, function($v, $w) { 
    if ($v) $v .= ','; 
    return $v . $w->foo; 
}); 
0

Se è un oggetto 1-livello, questo ha lavorato per me.

function implodeObjValues($glue, $obj) { 
    $s = ""; 
    foreach($obj[1] as $n=>$v) { 
     $s .= $glue . $v; 
    } 
    return substr($s,strlen($glue)); 
} 

function implodeObjLabels($glue, $obj) { 
    $s = ""; 
    foreach($obj[1] as $n=>$v) { 
     $s .= $glue . $n; 
    } 
    return substr($s,strlen($glue)); 
} 

Potrebbe includere un processo multilivello di tipo, ma non ne avevo ancora bisogno. Spero che questo aiuti.

Handy per la conversione di oggetti MySQL in array.

$db = new mysqli("localhost",$usr,$pw,$db); 
$row = $db->query("SHOW TABLES"); 
$a = implodeObjValues("|",$row); 
5

si può effettivamente impostare __toString() sulla classe come suggerito da Ray, ma non c'è bisogno di scorrere il array prima. implode() chiamerà direttamente la funzione __toString() degli oggetti (che funziona anche con gli array associativi, btw).

1
echo implode("','",(array)$data->stdArray); 
6

Questo è in realtà il modo migliore che ho trovato, non sembra essere risolta qui correttamente come la serie di oggetti dovrebbe essere in grado di gestire dimensione dinamica.

$str = implode(',', array_map(function($x) { return $x->foo; }, $a)); 

Anche questa sembra la soluzione più pulita che abbia mai visto.