Как использовать implode для массива объектов stdClass?
У меня есть массив объектов stdClass
, и я хочу построить список, разделенный запятыми, используя одно конкретное поле всех этих объектов 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);
И я хочу имплод на foo
всех stdClass
объектов в этом массиве, чтобы создать разделенный запятыми список. Итак, желаемый результат:
4,16,76
Есть ли способ сделать это с помощью implode (или какой-либо другой таинственной функции) без необходимости пропускать этот массив объектов через цикл?
8 ответов:
Вы могли бы использовать
array_map()
иimplode()
...$a = array_map(function($obj) { return $obj->foo; }, array(1=>$obj1 , 2=>$obj2 , 3=>$obj3)); $a = implode(", ", $a);
На самом деле это лучший способ, который я нашел, кажется, что здесь нет правильного ответа, поскольку массив объектов должен быть в состоянии обрабатывать динамический размер.
$str = implode(',', array_map(function($x) { return $x->foo; }, $a));
Это также кажется самым чистым решением, которое я видел.
Вы действительно можете установить
__toString()
в классе, предложенном Рэем, но вам не нужно сначала перебиратьarray
.implode()
будет непосредственно вызывать функцию__toString()
объектов (которая также работает с ассоциативными массивами, кстати).
Очень аккуратным решением для этого является
array_reduce()
функция, которая сводит массив к одному значению:$str = array_reduce($a, function($v, $w) { if ($v) $v .= ','; return $v . $w->foo; });
Я думаю, что проще всего было бы создать индексированный массив ID, а затем вызвать implode на 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));
Нет, лучшее, что вы можете сделать, это выполнить итерацию, вызвать tostring() для объекта и поместить результаты в новый массив для вызова implode.
Если это объект 1-го уровня, это сработало для меня.
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)); }
Может включать многоуровневый процесс по типу, но мне это пока не нужно. Надеюсь, это поможет.
Удобно для преобразования объекта MySQL обратно в массив.
$db = new mysqli("localhost",$usr,$pw,$db); $row = $db->query("SHOW TABLES"); $a = implodeObjValues("|",$row);