Réjôme
Réjôme

Reputation: 1484

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 for loop but I am looking for a really elegant way to do it. I tried with map() or each() without success.

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

Upvotes: 3

Views: 3624

Answers (2)

Jeffz
Jeffz

Reputation: 2105

This is old, but a bit different approach - works in Laravel 5.1 and up.

//your collection
$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'],
])

//one-liner to get you what you want
$result = explode(',', $breadcrumbs->implode('link', ','));

//here is what you will get:
array:4 [▼
  0 => "http://domain/aaa"
  1 => "http://domain/aaa/bbb"
  2 => "http://domain/aaa/bbb/ccc"
  3 => "http://domain/aaa/bbb/ccc/ddd"
]

Upvotes: 0

Joel Hinz
Joel Hinz

Reputation: 25394

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. :)

Upvotes: 3

Related Questions