• Czas czytania ~9 min
  • 01.03.2023

Wprowadzenie

Kolekcje Laravel są naprawdę potężne do pracy z tablicami danych. Zapewniają płynny, wygodny interfejs do wykonywania typowych operacji tablicowych, takich jak filtrowanie, formatowanie i przekształcanie danych. W tym poście na blogu omówimy niektóre z kluczowych funkcji kolekcji Laravel i sposoby ich wykorzystania do uproszczenia i usprawnienia kodu.

Tworzenie kolekcji

Najprostszym sposobem utworzenia kolekcji jest przekazanie tablicy do metody collect():

$collection = collect(1, 2, 3, 4, 5);

Podczas pracy z modelami elokwentnymi i konstruktorem zapytań domyślnie zwróci również kolekcję.

$users = User::query()
    ->where('is_active', true)
    ->get();

Filtrowanie danych

Kolekcje Laravel mają wiele różnych metod, które pozwalają nam filtrować dane w naszych kolekcjach. Pokażę ci kilka metod, które można wykorzystać do tego celu.

filter()

Jest to najczęstsza metoda filtrowania danych w kolekcji. Usunie wszystkie elementy, które zwracają wartość false dla danego wywołania zwrotnego.

$users = collect([
    ['name' => 'John Doe', 'is_active' => true],
    ['name' => 'Mary Doe', 'is_active' => true],
    ['name' => 'Peter Doe', 'is_active' => false],
]);

$filtered = $users->filter(fn ($user) => $user['is_active']);
// [
//     ['name' => 'John Doe', 'is_active' => true],
//     ['name' => 'Mary Doe', 'is_active' => true],
// ]

Można również wywołać metodę filter() bez wywołania zwrotnego. W takim przypadku usunie wszystkie elementy, które są fałszywe / puste, takie jak null, false, '', 0, [].

Ważne jest, aby pamiętać, że ta metoda nie stosuje żadnych zmian do oryginalnej kolekcji, tworzy zupełnie nową kolekcję z filtrowanymi elementami. Podobnie jak metoda where() używana

where()

dla zapytań Eloquent, metoda where() może być używana do filtrowania danych na podstawie klucz/wartość.

$users = collect([
    ['name' => 'John Doe', 'age' => 15],
    ['name' => 'Mary Doe', 'age' => 20],
    ['name' => 'Peter Doe', 'age' => 30],
    ['name' => 'George Doe', 'age' => 20],
]);

$filtered = $users->where('age', 20);
// [
//     ['name' => 'Mary Doe', 'age' => 20],
//     ['name' => 'George Doe', 'age' => 20],
// ]

Operator porównania można również przekazać jako drugi parametr, podobnie jak metodę Eloquent where().

$users = collect([
    ['name' => 'John Doe', 'age' => 15],
    ['name' => 'Mary Doe', 'age' => 20],
    ['name' => 'Peter Doe', 'age' => 30],
    ['name' => 'George Doe', 'age' => 20],
]);

$filtered = $users->where('age', '>=', 20);
// [
//     ['name' => 'Mary Doe', 'age' => 20],
//     ['name' => 'Peter Doe', 'age' => 30],
//     ['name' => 'George Doe', 'age' => 20],
// ]

Należy pamiętać, że metoda where() sprawdza tylko, czy wartość jest taka sama, a nie typ, więc 20 i "20" będą takie same. Aby sprawdzić wartość i typ, można zamiast tego użyć metody whereStrict().

Można również filtrować wiele wartości za pomocą metody whereIn() i według zakresu wartości za pomocą metody whereBetween()

$users = collect([
    ['name' => 'John Doe', 'age' => 15],
    ['name' => 'Mary Doe', 'age' => 20],
    ['name' => 'Peter Doe', 'age' => 30],
    ['name' => 'George Doe', 'age' => 20],
]);

$filtered = $users->whereIn('age', [20, 30]);
// [
//     ['name' => 'Mary Doe', 'age' => 20],
//     ['name' => 'Peter Doe', 'age' => 30],
//     ['name' => 'George Doe', 'age' => 20],
// ]
$users = collect([
    ['name' => 'John Doe', 'age' => 15],
    ['name' => 'Mary Doe', 'age' => 20],
    ['name' => 'Peter Doe', 'age' => 30],
    ['name' => 'George Doe', 'age' => 20],
]);

$filtered = $users->whereBetween('age', [15, 20]);
// [
//     ['name' => 'John Doe', 'age' => 15],
//     ['name' => 'Mary Doe', 'age' => 20],
//     ['name' => 'George Doe', 'age' => 20],
// ]

Należy pamiętać, że te metody nie stosują żadnych zmian do oryginalnej kolekcji, tworzą zupełnie nową kolekcję z filtrowanymi elementami.

first()

Ta metoda zwraca pierwszy element kolekcji, który zwraca wartość true dla danego wywołania zwrotnego.

$users = collect([
    ['name' => 'John Doe', 'age' => 15],
    ['name' => 'Mary Doe', 'age' => 20],
    ['name' => 'Peter Doe', 'age' => 30],
]);

$filtered = $users->first(fn ($user) => $user['age'] > 18);
// ['name' => 'Mary Doe', 'age' => 20]

Można również wywołać metodę first() bez wywołania zwrotnego. W takim przypadku zwróci pierwszą pozycję Kolekcji.

$users = collect([
    ['name' => 'John Doe', 'age' => 15],
    ['name' => 'Mary Doe', 'age' => 20],
    ['name' => 'Peter Doe', 'age' => 30],
]);

$filtered = $users->first(fn ($user) => $user['age'] > 18);
// ['name' => 'John Doe', 'age' => 15]

Aby zgłosić wyjątek, jeśli nie zostanie znaleziony żaden wynik, można zamiast tego użyć metody firstOrFail(). W takim przypadku, jeśli żaden element nie zostanie znaleziony, zostanie zgłoszony wyjątek Illuminate\Support\ItemNotFoundException.

last()

Ta metoda zwraca ostatni element kolekcji, który zwraca true dla danego wywołania zwrotnego.

$users = collect([
    ['name' => 'John Doe', 'age' => 15],
    ['name' => 'Mary Doe', 'age' => 20],
    ['name' => 'Peter Doe', 'age' => 30],
]);

$filtered = $users->last(fn ($user) => $user['age'] > 18);
// ['name' => 'Peter Doe', 'age' => 30]

Można również wywołać metodę last() bez wywołania zwrotnego. W takim przypadku zwróci ostatnią pozycję Kolekcji.

$users = collect([
    ['name' => 'John Doe', 'age' => 15],
    ['name' => 'Mary Doe', 'age' => 20],
    ['name' => 'Peter Doe', 'age' => 30],
]);

$filtered = $users->first(fn ($user) => $user['age'] > 18);
// ['name' => 'Peter Doe', 'age' => 30]

only()

Ta metoda może być użyta do odfiltrowania potrzebnych przedmiotów z kolekcji na podstawie kluczy.

$user = collect([
    'id' => 1,
    'name' => 'John Doe',
    'email' => '[email protected]
ї', 'username' => 'john_doe', ]); $filtered = $user->only(['name', 'email']); // ['name' => 'John Doe', 'email' => '[email protected]']

Ważne jest, aby pamiętać, że ta metoda nie stosuje żadnych zmian do oryginalnej kolekcji, tworzy zupełnie nową kolekcję z filtrowanymi elementami. Podobnie jak metoda where() używana

except()

Ta metoda może być użyta do odfiltrowania niechcianych elementów z kolekcji na podstawie kluczy.

$user = collect([
    'id' => 1,
    'name' => 'John Doe',
    'email' => '[email protected]',
    'username' => 'john_doe',
]);

$filtered = $user->except(['name', 'email']);
// ['id' => 1, 'username' => 'john_doe']

Ważne jest, aby pamiętać, że ta metoda nie stosuje żadnych zmian do oryginalnej kolekcji, tworzy zupełnie nową kolekcję z filtrowanymi elementami. Podobnie jak metoda where() używana

Formatowanie i przekształcanie danych

Często zdarza się, że aplikacje pobierają dane, zapętlają je, aby przekształcić wartość i wypchnąć sformatowaną wartość do zmiennej tymczasowej. Zamiast tego możemy użyć metody map(), która wykona podane wywołanie zwrotne w każdym elemencie Kolekcji i zwróci nową kolekcję z przekształconymi/sformatowanymi wartościami.

$users = collect([
    ['name' => 'John Doe', 'email' => '[email protected]', 'is_active' => true],
    ['name' => 'Mary Doe', 'email' => '[email protected]', 'is_active' => true],
    ['name' => 'Peter Doe', 'email' => '[email protected]', 'is_active' => true],
]);

$userModels = $users->map(fn ($user) => new User($user));

Debugowanie kolekcji

Czasami musimy debugować wartości naszych kolekcji, a kolekcje Laravel mają dwie metody od razu po wyjęciu z pudełka, aby nam w tym pomóc.

dump()

Ta metoda zrzuca elementy kolekcji i kontynuuje wykonywanie skryptu.

dd()

Ta metoda zrzuca elementy kolekcji i kończy wykonywanie skryptu.

Ukryte klejnoty

Oprócz metod już przedstawionych w powyższych sekcjach. Istnieją pewne metody, które nie są używane tak często lub nie są bardzo dobrze znane, ale mogą zmienić zasady gry w zależności od tego, nad czym pracujemy. Poniżej wymienię niektóre z metod, które moim zdaniem powinieneś znać.

undot()

Ta metoda może być używana do przekształcania ciągów z kropkami w tablice.

$data = collect([
    'user.first_name' => 'John',
    'user.last_name' => 'Doe',
    'user.email' => '[email protected]',
    'user.social.twitter' => '@john_doe',
    'user.social.github' => 'JohnDoe',
]);

$user = $data->undot();
// [
//     "user" => [
//         "first_name" => "John",
//         "last_name" => "Doe",
//         "email" => "[email protected]",
//         "social" => [
//             "twitter" => '@john_doe',
//             "github" => 'JohnDoe',
//         ],
//     ],
// ]

partition()

Ta metoda rozdziela elementy kolekcji na dwa różne w zależności od podanego wywołania zwrotnego. Przedmioty, które zwracają wartość true dla danego wywołania zwrotnego, zostaną wepchnięte do pierwszej kolekcji, a te, które zwracają false, zostaną wepchnięte do drugiej.

$users = collect([
    ['name' => 'John Doe', 'is_active' => true],
    ['name' => 'Mary Doe', 'is_active' => false],
    ['name' => 'Peter Doe', 'is_active' => true],
]);

[$activeUsers, $inactiveUsers] = $users->partition(fn ($user) => $user['is_active']);

$activeUsers->all();
// [
//     ['name' => 'John Doe', 'is_active' => true],
//     ['name' => 'Peter Doe', 'is_active' => true],
// ]

$inactiveUsers->all();
// [
//     ['name' => 'Mary Doe', 'is_active' => false],
// ]

reject()

Jest to przeciwieństwo metody filter(), ale nie jest tak dobrze znane. Usunie wszystkie elementy, które zwracają wartość true dla danego wywołania zwrotnego.

$users = collect([
    ['name' => 'John Doe', 'is_active' => true],
    ['name' => 'Mary Doe', 'is_active' => true],
    ['name' => 'Peter Doe', 'is_active' => false],
]);

$filtered = $users->reject(fn ($user) => $user['is_active']);
// [
//     ['name' => 'Peter Doe', 'is_active' => false],
// ]

random()

Ta metoda zwraca losowy element z Kolekcji.

$data = collect([1, 2, 3, 4, 5]);

$data->random();
// 3 - randomly selected

Jeśli chcesz pobrać więcej niż jeden element, możesz przekazać liczbę całkowitą jako argument.

$data = collect([1, 2, 3, 4, 5]);

$data->random(2);
// [2, 3] - randomly selected

isEmpty()

Ta metoda zwraca wartość true, jeśli kolekcja nie ma żadnych elementów lub false, jeśli ma co najmniej jeden element.

collect([])->isEmpty(); // true
collect([1])->isEmpty(); // false

isNotEmpty()

Ta metoda jest przeciwieństwem metody isEmpty(). Zostanie zwrócona wartość true, jeśli kolekcja zawiera co najmniej jeden przedmiot i false, jeśli nie ma na niej żadnych przedmiotów. Wiadomości wysokiego rzędu

collect([])->isNotEmpty(); // false
collect([1])->isNotEmpty(); // true

 

are like shortcuts that we can use to apply common actions in our Collections. The methods that support this feature are: average(), avg(), contains(), each(), every(), filter(), first(), flatMap(), groupBy(), keyBy(), map(), max(), min(), partition(), reject(), skipUntil(), skipWhile(), some(), sortBy(), sortByDesc(), sum(), takeUntil(), takeWhile(), and unique().

Wyobraź sobie, że musisz wysłać biuletyn do wszystkich subskrybowanych użytkowników. Korzystając z tej funkcji, możesz zrobić coś takiego.

User::query()
    ->where('receive_newsletter', true)
    ->each
    ->sendNewsletter();

Kolekcje Lazy Collections

są naprawdę potężne, a LazyCollections rozszerza ich moc za pomocą generatorów, dzięki czemu możemy pracować z dużymi zestawami danych, ale utrzymując niskie zużycie pamięci.

Wyobraź sobie, że mamy miliony produktów w naszej bazie danych i musimy wykonać na nich pewne działania, możemy użyć metody cursor() z Eloquent/Query Builder, aby zwrócić LazyCollection zamiast normalnej kolekcji.

$payments = Payment::query()
    ->where('is_accepted', true)
    ->cursor()
    ->map(fn ($payment) => $this->formatPaymentData($payment));

foreach ($payments as $payment) {
    // LOGIC HERE
}

W powyższym przykładzie pojedyncze zapytanie zostanie uruchomione w bazie danych, ale będzie również przechowywać tylko jeden element w pamięci naraz. Ponadto wywołanie zwrotne map() nie zostanie wykonane od razu, ale tylko wtedy, gdy wykonamy iterację każdego pojedynczego elementu w instrukcji foreach .

Tworzenie własnych metod kolekcji

Oprócz wszystkich niesamowitych metod, które Kolekcje mają już po wyjęciu z pudełka, możemy tworzyć własne metody, ponieważ są one "makroowalne". Oznacza to, że możemy użyć metody macro(), aby rozszerzyć je o nasze własne metody. W tym celu musimy dodać nasze nowe metody niestandardowe w metodzie boot() klasy AppServiceProvider.Conclusion

class AppServiceProvider extends ServiceProvider
{
    public function boot()
    {
        Collection::macro('toSlug', function () {
            return $this->map(fn ($value) => Str::slug($value, '-'));
        });
    }
}

.


To tylko kilka przykładów z wielu potężnych metod dostępnych w Laravel Collections. Korzystając z tych metod, można łatwo i wydajnie manipulować danymi, dzięki czemu kod jest bardziej czytelny i łatwiejszy w utrzymaniu.

Mam nadzieję, że spodobał Ci się ten artykuł, a jeśli tak, nie zapomnij podzielić się tym artykułem ze znajomymi!!! Nara! :wink:

Ostatnia aktualizacja 1 miesiąc temu.

Comments

No comments yet
Yurij Finiv

Yurij Finiv

Full stack

O

Professional Fullstack Developer with extensive experience in website and desktop application development. Proficient in a wide range of tools and technologies, including Bootstrap, Tailwind, HTML5, CSS3, PUG, JavaScript, Alpine.js, jQuery, PHP, MODX, and Node.js. Skilled in website development using Symfony, MODX, and Laravel. Experience: Contributed to the development and translation of MODX3 i...

O autorze CrazyBoy49z
WORK EXPERIENCE
Kontakt
Ukraine, Lutsk
+380979856297