Skip to content

Commit

Permalink
refs #119 Added init Collection
Browse files Browse the repository at this point in the history
  • Loading branch information
tabuna committed Apr 6, 2024
1 parent 86a46fb commit 46696a5
Show file tree
Hide file tree
Showing 5 changed files with 210 additions and 0 deletions.
1 change: 1 addition & 0 deletions routes/web.php
Original file line number Diff line number Diff line change
Expand Up @@ -53,6 +53,7 @@
Route::view('/library/upgrade', 'library.upgrade')->name('library.upgrade');
Route::view('/library/security', 'library.security')->name('library.security');
Route::view('/library/how-to-ask', 'library.how-to-ask')->name('library.how-to-ask');
Route::view('/library/collection', 'library.collection')->name('library.collection');

/*
|--------------------------------------------------------------------------
Expand Down
17 changes: 17 additions & 0 deletions storage/library/collection/basics.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,17 @@
---
title: "Основы"
description: "Понимание основных принципов работы с коллекциями"
---

Использование коллекций не является обязательным элементом, они не добавляют новую функциональность в PHP, но
предоставляют удобный интерфейс для работы с массивами. При написании кода с использованием коллекций вы будете писать
более выразительный код упрощая множество операций с данными, таких как фильтрация, сортировка, слияние и трансформация
и т.д.

> [!NOTE]
> Результаты запросов `Eloquent` всегда возвращаются как экземпляры `Collection`.
Когда вы пишете код в императивном стиле, вы указываете, как выполнить задачу, в то время как декларативный стиль
позволяет описывать что вы хотите достичь, без явного указания шагов выполнения. Использование коллекций способствует
более декларативному подходу к программированию, где вы объявляете операции над данных, а не реализуете их самостоятельно.

71 changes: 71 additions & 0 deletions storage/library/collection/dont-primitives.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,71 @@
---
title: "Не используйте примитивы"
description: "Что-то написать"
---

Помимо явной цепочки вызовов, мы можем передавать промежуточные значения для дальнейшей обработки.
Например, в одном методе мы можем сформировать коллекцию активных пользователей, а в другом продолжить высокоуровневую обработку:

```php
function getActiveUsers(): array
{
// ...

$activeUsers = array_filter($activeUsers, function (User $user) {
return $user->isActive();
});

$activeUsers = array_filter($activeUsers, function (User $user) {
return !$user->isAdmin();
});

usort($activeUsers, function (User $a, User $b) {
return $a->created_at <=> $b->created_at;
});

retrun $activeUsers;
}


$activeUsers = getActiveUsers();

// Вычисление среднего возраста активных пользователей
$totalAge = 0;
foreach ($activeUsers as $user) {
$totalAge += $user->age;
}
$averageAge = $totalAge / count($activeUsers);

// Формирование списка электронных адресов активных пользователей
$emailList = [];
foreach ($activeUsers as $user) {
$emailList[] = $user->email;
}
```

```php
// Хорошо ✅
function getActiveUsers(): Collection
{
// ...

return $users
->filter(function (User $user) {
return $user->isActive();
})
->filter(function (User $user) {
return !$user->isAdmin();
})
->sortBy('created_at');
}



$activeUsers = getActiveUsers();

// Вычисление среднего возраста активных пользователей
$averageAge = $activeUsers->avg('age');

// Формирование списка электронных адресов активных пользователей
$emailList = $activeUsers->pluck('email');
```
34 changes: 34 additions & 0 deletions storage/library/collection/foreach.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,34 @@
---
title: "Не используйте циклы"
description: "Замените циклов на методы коллекций при обработке данных."
---

Циклы, такие как `foreach` и `for`, широко используются для обработки данных в PHP.
Однако, при использовании циклов код может стать трудночитаемым, запутанным, а следовательно подверженным ошибкам.
Рассмотрим следующий распространённый пример:

```php
// Плохо ❌
$activeUsers = [];

foreach ($users as $user) {
if ($user->isActive()) {
$activeUsers[] = $user;
}
}
```

Здесь мы используем цикл `foreach` для фильтрации активных пользователей.
Этот подход требует создания временного массива и ведет к увеличению объема кода.

При использовании коллекций доступно множество методов, таких как `filter`, `map`, `reduce`, которые позволяют заменить типичные циклы на более элегантные и понятные конструкции. Перепишем предыдущий пример, используя метод `filter`:

```php
// Хорошо ✅
$activeUsers = $users->filter(function (User $user) {
return $user->isActive();
});
```

Этот код короче, проще читается и не требует создания временного массива.
Метод `filter` применяет заданное условие к каждому элементу коллекции, возвращая только те, которые соответствуют критерию.
87 changes: 87 additions & 0 deletions storage/library/collection/thinking-in-steps.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,87 @@
---
title: "Думай поэтапно"
description: "Замените циклов на методы коллекций при обработке данных."
---

В программировании часто возникают задачи, требующие последовательного выполнения нескольких шагов для достижения
конечного результата. Методология "Думая поэтапно" помогает справиться с такими задачами, разбивая их на более мелкие,
управляемые этапы. Давайте рассмотрим, как мы можем использовать методы коллекций в PHP для реализации этого подхода.

Давайте снова вернёмся к примеру с фильтрацией активных пользователей:

```php
// Плохо ❌
$activeUsers = [];

foreach ($users as $user) {
if ($user->isActive()) {
$activeUsers[] = $user;
}
}
```

Теперь нам нужно добавить ещё один шаг: убрать администраторов из списка активных пользователей и мы не хотим
использовать массивы:

```php
// Лучше, но не идеально ❌
$activeUsers = array_filter($activeUsers, function (User $user) {
return $user->isActive();
});

$activeUsers = array_filter($activeUsers, function (User $user) {
return !$user->isAdmin();
});
```

Нам пришлось объявить переменную `$activeUsers` дважды, но это не самое худшее.

При использовании коллекции каждый вызов метода, это отдельный шаг, который можно легко прочитать и понять:

```php
// Хорошо ✅
$activeUsers = $users
->filter(function (User $user) {
return $user->isActive();
})
->filter(function (User $user) {
return !$user->isAdmin();
});
```


Теперь введём ещё одно условие, нам нужно отсортировать пользователей по дате регистрации:

```php
// Лучше, но не идеально ❌
$activeUsers = array_filter($activeUsers, function (User $user) {
return $user->isActive();
});

$activeUsers = array_filter($activeUsers, function (User $user) {
return !$user->isAdmin();
});

usort($activeUsers, function (User $a, User $b) {
return $a->created_at <=> $b->created_at;
});
```

Используя методы коллекций, мы можем добавить сортировку в цепочку методов:

```php
// Хорошо ✅
$activeUsers = $users
->filter(function (User $user) {
return $user->isActive();
})
->filter(function (User $user) {
return !$user->isAdmin();
})
->sortBy('created_at');
```


Использование методов коллекций позволяет нам более явно выразить наши намерения при обработке данных, делая код более
структурированным и легким для понимания.

0 comments on commit 46696a5

Please sign in to comment.