5

I have an array of objects. Something like this:

$my_array = [
    (object) ['name' => 'name 0'],
    (object) ['name' => 'name 1'],
    (object) ['name' => 'name 2'],
];

And I'd like to reduce it to a concatenation of all name properties like:

name 0 / name 1 / name 2

One way would be:

$result = [];
foreach ($my_array as $item) {
    $result[] = $item->name;
}
echo implode(' / ', $result);

But I'd prefer something more compact, like using array_map:

implode(' / ', array_map(function($item) {
    return $item->name; 
}, $my_array ));

Given that in fact I want to reduce and array to a string I thought it would be cleaner with array_reduce but the only solution I can come out with is:

array_reduce($my_array, function($carry, $obj) {
    return empty($carry) ? $obj->name : $carry .= " / $obj->name"; 
});

Yet it doesn't feel cleaner... So the question is simple:

Can anybody think of an understandable better/cleaner solution?

Jordi Nebot
  • 3,355
  • 3
  • 27
  • 56
  • 4
    You should choose the solution which is __understandable__. And not which is cleaner and/or shorter. – u_mulder Jul 07 '17 at 08:57
  • Thanks @PrafullaKumarSahu `get_object_vars` returns `NULL` since `$my_array` isn't an object but an array of objects. What's your point? – Jordi Nebot Jul 07 '17 at 08:59
  • Ok @u_mulder, but I'm asking because maybe there's a better (cleaner and understandable) solution than mine. I edited my question. Thank you :) – Jordi Nebot Jul 07 '17 at 09:02

2 Answers2

7

You might be looking for array_column(), which takes the values of the given column:

$result = array_column($largeArray, 'name');// take all values with the key 'name'

// If you want it with a slash:
echo implode(" / ", $result);

Doesn't need much more explanation. Which is the kind of code you should go for. Weird functionality that feels fancy, but nobody can understand is worse. You might understand what it does now, but if you leave it alone for 6 months and come back, you've forgotten it just as much.

Often: maintainability > complexity (and sometimes even >performance)

Martijn
  • 15,791
  • 4
  • 36
  • 68
  • It's one of those functions you don't use on a daily basis, but in cases like this, it's perfect. And because it uses a PHP function instead of a sef written loop, I'm guessing the performance is better (as looping in PHP never is really fast) – Martijn Jul 07 '17 at 09:26
2
trim (array_reduce($my_array, function($carry, $obj) {
    return "$carry / {$obj->name}"; 
}), " /");

Is a bit more cleaner to my taste, but may have some side-effects. If the first name starts with '/' or the last name end with '/', they would be lost. e.g:

$my_array = [
    (object) ['name' => '/name 0'],
    (object) ['name' => 'name 1'],
    (object) ['name' => 'name 2/'],
];

results with /name 0 / name 1 / name 2/ with the original code, and name 0 / name 1 / name 2 when trim is used.

Alex Blex
  • 34,704
  • 7
  • 48
  • 75