Be part of JetBrains PHPverse 2026 on June 9 – a free online event bringing PHP devs worldwide together.

madsynn's avatar

Trying to group my query into alphabetic chunks

Any help would be awesome.

my query so far but not sure how to connect each set of letters.

$partners = Directory::where('name', 'like', 'A%')->orderBy('name', 'asc')->get();

returns all with start letter A just fine but i want to group them into [A,B,C,D] and keeps them in that order.

I can do a query for each one but not practical so i want to output them as grouped and any help you can give would be appreciated.

my blade file loop

@foreach($partners as $letter => $group)

    <ul>

        <li>{{ $letter }}</li> // WOULD LIKE THIS TO BE " A - B - C - D "

        @foreach($group as $partner)

            <li>{{ $partner['name'] }}</li>

        @endforeach

    </ul>

@endforeach

thnx in advance

0 likes
28 replies
jlrdw's avatar

Do you want all grouped by letter or just the letter entered into a search?

bugsysha's avatar
$partners = Directory::query()->orderBy('name')->get()->groupBy(function (Directory $directory): string {
  return ($directory->name)[0];
});
@foreach($partners as $letter => $group)

    <div>{{ $letter }}</div> // WOULD LIKE THIS TO BE " A - B - C - D "

    <ul>

        @foreach($group as $partner)

            <li>{{ $partner->name }}</li>

        @endforeach

    </ul>

@endforeach
MichalOravec's avatar
$directories = Directory::orderBy('name')->get()->groupBy(function ($directory) {
    return strtoupper($directory->name[0]);
});
@foreach($directories as $letter => $group)
    <div>{{ $letter }}</div>

    <ul>
        @foreach($group as $directory)
            <li>
                {{ $directory->name }}
            </li>
        @endforeach
    </ul>
@endforeach

Docs: https://laravel.com/docs/8.x/collections#method-groupby

madsynn's avatar

@michaloravec and @bugsysha

Thank you for your help. I almost have what i need. Guess i should have expained better i am trying to group the letters into sections as follows and then loop through them.

The following are just arrays explaining what i am trying to do after i have queried the names. I am aware they will not work as coding i am just trying to explain what i mean.

Trying to create this. https://nimb.ws/57f2B8

Section with names starting with :

$a_though_d = [A,B,C,D];
$e_though_h = [E,F,G,H];
$i_though_l = [I,J,K,L];
$m_though_p = [M,N,O,P];
$q_though_t = [Q,R,S,T];
$u_though_x = [Y,Z];
madsynn's avatar

@jlrdw thnx;

Trying to group into groups of letters if that makes sense. Look at my new comment below I also added a screenshot. I can separate them into each letter but not sure how to group them into groups of letters.

bugsysha's avatar
$partners = Directory::query()->orderBy('name')->get()->groupBy(function (Directory $directory): string {
  $letter = $directory->name[0];
  return in_array($letter, range('A', 'Z')) ? $letter : 'Other';
})->chunk(4);
@foreach($partners as $letter => $group)

    <div>{{ $letter }}</div> // WOULD LIKE THIS TO BE " A - B - C - D "

    <ul>

        @foreach($group as $partner)

            <li>{{ $partner->name }}</li>

        @endforeach

    </ul>

@endforeach
MichalOravec's avatar

Yeah chunk will work.

$directories = Directory::orderBy('name')->get()->groupBy(function ($directory) {
    return strtoupper($directory->name[0]);
});
@foreach ($directories->chunk(4) as $chunk)
    @foreach($chunk as $letter => $group)
        <div>{{ $letter }}</div>

        <ul>
            @foreach($group as $directory)
                <li>
                    {{ $directory->name }}
                </li>
            @endforeach
        </ul>
    @endforeach
@endforeach

Docs: https://laravel.com/docs/8.x/collections#method-chunk

madsynn's avatar

@bugsysha

Thank you that is right along the lines i need but with couple new questions.

Here is my output when I run it with DD.

https://nimb.ws/kL70Ez

When I try to output to the view i get an error saying name is not part of the collection but it clearly is.

Next question is there a way to make the "OTHER" last in the output so each group follows the earlier screenshot.

Thank you by the way you rock.

madsynn's avatar

@michaloravec Thank you but still not quite what i am looking for. Its almost there.

This is a dump of what you sent me. https://nimb.ws/bnNwQ0

It looks like the loop is just grabbing the first letter and grouping them into the letter they start with and no other data. When i output the loop it says not name on this collection. Same problem i keep running into. so the output to the blade file errors out.

Thank you so much for helping me tackle this.

bugsysha's avatar
$partners = Directory::query()->orderBy('name')->get()->groupBy(function (Directory $directory): string {
  $letter = $directory->name[0];
  return in_array($letter, range('A', 'Z')) ? $letter : 'Other';
})->sortBy(function (string $text, string $key):int {
  return collect(range('A', 'Z'))->flip()->get($key, 100);
})->chunk(4);
@foreach($partners as $letter => $group)

    <div>{{ $letter }}</div> // WOULD LIKE THIS TO BE " A - B - C - D "

    <ul>

        @foreach($group as $partner)

            <li>{{ $partner->name }}</li>

        @endforeach

    </ul>

@endforeach
bugsysha's avatar

@madsynn also please fully expand one collection and post a screenshot, let's say A just to see what is the contents so I can answer that other question where no name on the collection.

1 like
bugsysha's avatar

I've forgot about chunking.

@foreach($partners as $partnerChunk)

  @foreach($partnerChunk as $letter => $group)

    <div>{{ $letter }}</div> // WOULD LIKE THIS TO BE " A - B - C - D "

    <ul>

        @foreach($group as $partner)

            <li>{{ $partner->name }}</li>

        @endforeach

    </ul>

  @endforeach

@endforeach
MichalOravec's avatar

You got that result because I used chunk in the foreach loop.

madsynn's avatar

@bugsysha

Almost have it. it is outputting to blade now but its outputting per letter not per group.

A
 AbeT 
 Agilant
 Alde 
 Allscript 
 AM Mobile
 Appetize
 Appogee
 Arlington 
 Atlanta Computer 

B
 Bar   Unlimited
 Barcodes Inc.
 Biz  POS
 Brad  Incorporated

The chunk in the foreach was what was grouping them correctly though wasn't it.

Now how do I group them together without it?

bugsysha's avatar

@madsynn I'm not sure what is not correct at this moment. Show me an example what you want to output.

bugsysha's avatar

@madsynn maybe I do get it.

@foreach($partners as $partnerChunk)

  @foreach($partnerChunk as $group)

    <div>{{ $partnerChunk->keys()->implode(' - ') }}</div> // WOULD LIKE THIS TO BE " A - B - C - D "

    <ul>

        @foreach($group as $partner)

            <li>{{ $partner->name }}</li>

        @endforeach

    </ul>

  @endforeach

@endforeach
madsynn's avatar

@bugsysha

Thank you so much for helping me tackle this.

Once they are grouped and outputing how do o loop through each group so i can style them differently?

Each section is in its own container and styled a little differently.

bugsysha's avatar
bugsysha
Best Answer
Level 61
@foreach($partners as $partnerChunk)

  @foreach($partnerChunk as $group)

    <div class="{{ $partnerChunk->keys()->implode('') }}">{{ $partnerChunk->keys()->implode(' - ') }}</div> // WOULD LIKE THIS TO BE " A - B - C - D "

    <ul>

        @foreach($group as $partner)

            <li>{{ $partner->name }}</li>

        @endforeach

    </ul>

  @endforeach

@endforeach
.ABCD { background: red; }
.EFGH { background: black; }
bugsysha's avatar
@foreach($partners as $partnerChunk)

  @foreach($partnerChunk as $group)

@if ($loop->first)
    <div class="{{ $partnerChunk->keys()->implode('') }}">{{ $partnerChunk->keys()->implode(' - ') }}</div> // WOULD LIKE THIS TO BE " A - B - C - D "
@endif

    <ul>

        @foreach($group as $partner)

            <li>{{ $partner->name }}</li>

        @endforeach

    </ul>

  @endforeach

@endforeach
1 like
madsynn's avatar

@bugsysha

Thank you very much. You really made that look easy and I appreciate the help. Its not like the stuff I code normally and appreciate it very much.

You totally rock!

bugsysha's avatar

You are very welcome. Thank you for the Best Reply award.

jlrdw's avatar

I know you amost have it, but I would use

GROUP BY substr(your_field, 1, 1)
ORDER BY your_field ASC   // 

But write query where first round less than e

second round greater than d less than i

etc.

You can work out your counter.

But I usually don't use eloquent, I usually use getPdo() and write regular queries.

madsynn's avatar

@bugsysha

I was wondering if i could get your help one more time. This works great but i need one more adjustment if you could help please.

@foreach($partners as $partnerChunk)

  @foreach($partnerChunk as $group)

@if ($loop->first)
    <div class="{{ $partnerChunk->keys()->implode('') }}">{{ $partnerChunk->keys()->implode(' - ') }}</div> // WOULD LIKE THIS TO BE " A - B - C - D "
@endif

    <ul>

        @foreach($group as $partner)

            <li>{{ $partner->name }}</li>

        @endforeach

    </ul>

  @endforeach

@endforeach

This outputs correctly but in one big list. I need it to do tow sections at a time for a total of 4 columns.

Can you help me get the code right. thank you.

bugsysha's avatar

Not sure I understand two sections at a time for a total of 4 columns, but you need to use CSS for that. I use TailwindCSS so for me that would be something like <div class="grid grid-cols-4"> columns here </div>.

Please or to participate in this conversation.