Réjôme Réjôme - 1 year ago 69
PHP Question

How to concatenate values of a laravel collection

Here is a small challenge for Laravel fanboys :-)

I want to build a simple list of request segments along to their url.

I start with:

// http://domain/aaa/bbb/ccc/ddd
$breadcrumbs = collect(explode('/', $request->path()))

But I don't know how to map it to a collection looking like:

$breadcrumbs = collect([
['title' => 'aaa', 'link' => 'http://domain/aaa'],
['title' => 'bbb', 'link' => 'http://domain/aaa/bbb'],
['title' => 'ccc', 'link' => 'http://domain/aaa/bbb/ccc'],
['title' => 'ddd', 'link' => 'http://domain/aaa/bbb/ccc/ddd'],

I could easily do it with a
loop but I am looking for a really elegant way to do it. I tried with
without success.

As Adam Wathan says: "Never write another loop again." ;-)

Answer Source

There are quite a few ways you can go about doing this, but since you will inevitably require knowledge of past items, I would suggest using reduce(). Here's a basic example that will show you how to build up the strings. You could easily add links, make the carry into an array, etc.

collect(['aaa', 'bbb', 'ccc', 'ddd'])
    ->reduce(function ($carry, $item) {
        return $carry->push($carry->last() . '/' . $item);
    }, collect([]));

Results in

Illuminate\Support\Collection {#928
    #items: array:4 [
        0 => "/aaa"
        1 => "/aaa/bbb"
        2 => "/aaa/bbb/ccc"
        3 => "/aaa/bbb/ccc/ddd"

Not claiming it's by any means optimised, but it does work. :)