How to use implode a column from an array of stdClass objects? [duplicate]
Asked Answered
S

9

26

I have an array of stdClass objects and I want to build a comma separated list using one specific field of all those stdClass objects. My array looks like this:

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

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

And I want to implode on foo of all the stdClass objects in that array to create a comma separated list. So the desired result is:

4,16,76

Is there any way to do this with implode (or some other mystery function) without having to put this array of objects through a loop?

Standridge answered 31/5, 2012 at 12:51 Comment(1)
maybe if you overload the toString() method of the object.Farrow
F
39

You could use array_map() and implode()...

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

$a = implode(", ", $a);
Fawnfawna answered 31/5, 2012 at 12:54 Comment(1)
This works and is cleaner than a loop, unfortunately I am finding that a foreach loop performs better. I'm getting similar results with array_reduce :( Guess I'll just stick with the foreach loop.Standridge
C
14

With PHP 7.0+ you can use array_column for this.

echo implode(',', array_column($a, 'foo'));
Crossfade answered 29/5, 2019 at 0:3 Comment(2)
Works only, if foo is declared public.Charlsiecharlton
@Charlsiecharlton Can you have non-public properties in a StdClass object?Intolerable
C
11

This is actually the best way I've found, it doesn't seem to be answered here properly as the array of objects should be able to handle dynamic size.

$str = implode(',', array_map(function($x) { return $x->foo; }, $a));
Carom answered 31/3, 2016 at 15:47 Comment(0)
N
7

You can actually set __toString() on the class as suggested by Ray, but you don't need to iterate through the array first. implode() will directly call the __toString() function of the objects (which also works with associative arrays, btw).

Nganngc answered 25/9, 2014 at 12:35 Comment(0)
I
6

A very neat solution for this is the array_reduce() function, that reduces an array to a single value:

$str = array_reduce($a, function($v, $w) {
    if ($v) $v .= ',';
    return $v . $w->foo;
});
Intervenient answered 31/5, 2012 at 12:58 Comment(0)
C
1
echo implode("','",(array)$data->stdArray);
Centiliter answered 26/1, 2015 at 18:28 Comment(0)
G
0

I guess the easiest way would be to create an ID indexed array and then call implode on 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));
Giffie answered 31/5, 2012 at 12:54 Comment(0)
N
0

No, the best you can do is iterate through, call tostring() on the object and put the results in a new array to call implode on.

Nonperformance answered 31/5, 2012 at 12:54 Comment(0)
F
0

If it's a 1-level object, this worked for 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));
}

Could include a by-type multi-level process, but I didn't need that yet. Hope this helps.

Handy for converting MySQL object back to array.

$db = new mysqli("localhost",$usr,$pw,$db);
$row = $db->query("SHOW TABLES");
$a = implodeObjValues("|",$row);
Fregger answered 8/8, 2014 at 15:41 Comment(0)

© 2022 - 2024 — McMap. All rights reserved.