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.