php_components_pack/sources/traits/ObjectArray/ObjectArrayLINQTrait.php
babaev-an 697f6b81b9 20250424
[Д] [ObjectArray->Add] Функция добавляет объект в массив объектов, хранящийся в данном классе (аналогично добавлению элемента в массив с помощью []).

[Д] [ObjectArray->AddRange] Функция добавляет массив объектов (или объекты, заданные с помощью array) в массив объектов, хранящийся в данном классе.

[И] [ObjectArray->Update] Добавление с помощью foreach заменено на AddRange.

[Д] [IDuplicated] Добавлен интерфейс реализации дублирования классов.

[Д] [IStoredAtSQL] Добавлен интерфейс поддержки моделей и классов, реализующих хранение свойств в SQL базе данных.
2025-04-24 07:31:59 +03:00

381 lines
17 KiB
PHP
Raw Blame History

This file contains ambiguous Unicode characters

This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.

<?php
namespace goodboyalex\php_components_pack\traits\ObjectArray;
use goodboyalex\php_components_pack\classes\ObjectArray;
/**
* Часть кода класса ObjectArray, отвечающая за LINQ-подобные операции.
*
* @author Александр Бабаев
* @package php_components_pack
* @version 1.0
* @since 1.0
*/
trait ObjectArrayLINQTrait
{
/**
* Возвращает объект, значение свойства которого минимально.
*
* @param callable $itemValuePredicate Функция, возвращающая значение свойства объекта.
* Параметром является объект массива.
*
* @return mixed|null Объект, значение свойства которого минимально
*/
public function MinBy (callable $itemValuePredicate): mixed
{
return array_reduce($this->Container,
fn ($min, $item) => $min === null || $itemValuePredicate($item) < $itemValuePredicate($min) ? $item : $min);
}
/**
* Возвращает объект, значение свойства которого максимально.
*
* @param callable $itemValuePredicate Функция, возвращающая значение свойства объекта.
* Параметром является объект массива.
*
* @return mixed|null Объект, значение свойства которого максимально.
*/
public function MaxBy (callable $itemValuePredicate): mixed
{
return array_reduce($this->Container,
fn ($max, $item) => $max === null || $itemValuePredicate($item) > $itemValuePredicate($max) ? $item : $max);
}
/**
* Выделяет из массива объектов объект, удовлетворяющий условию. Если объектов несколько, то выбирается первый
* встречающийся объект из них. Если объектов нет, вернёт false.
*
* @param callable|null $selectCondition Функция выборки объектов <code>fn (mixed $item): bool</code>. Вместо неё
* можно использовать null, тогда функция выберет текущий объект. По умолчанию, null.
*
* @return false|mixed Выбранный объект, удовлетворяющий условию, или false, если таких нет.
*/
public function GetRow (?callable $selectCondition = null): mixed
{
// Если условие не задано
if ($selectCondition === null || !is_callable($selectCondition)) {
// - то если массив не пуст
if (count($this->Container) > 0)
// -- возвращаем первый элемент
return $this->Container[0];
else
// -- иначе возвращаем false
return false;
}
// Получаем результаты выборки из массива по условию $selectCondition
$result = $this->GetRows($selectCondition);
// Если результат не найден
if (count($result) == 0)
// - возвращаем false
return false;
// Возвращаем результат
return $result[0];
}
/**
* Выделяет из массива объектов объекты, удовлетворяющие условию.
*
* @param callable|null $selectCondition Функция выборки объектов <code>fn (mixed $item): bool</code>. Вместо неё
* можно использовать null, тогда функция будет выбирать все объекты. По умолчанию, null.
*
* @return ObjectArray Массив объектов, удовлетворяющих условию
*/
public function GetRows (?callable $selectCondition = null): ObjectArray
{
// Если условие не задано
if ($selectCondition === null || !is_callable($selectCondition))
// - то возвращаем все элементы
return new ObjectArray($this->Container);
// Создаём результирующий массив
$result = [];
// Проходим по массиву
foreach ($this->Container as $item) {
// - пропускаем не объекты
if (!is_object($item))
continue;
// - если объект удовлетворяет условию
if ($selectCondition($item))
// -- добавляем его в результат
$result[] = $item;
}
// Возвращаем результат
return new ObjectArray($result);
}
/**
* Получение значение единичного поля. Если полей по выборке будет больше одного, то вернёт первое из них.
*
* @param string $column Требуемый столбец
* @param callable|null $wherePredicate Условие выборки <code>fn (mixed $item): bool</code>, которое проверяет,
* подходит элемент или нет.
*
* @return mixed|null Результат запроса или null в случае ошибки
*/
public function GetValue (string $column, ?callable $wherePredicate = null): mixed
{
// Получаю колонку
$result = $this->GetColumn($column, $wherePredicate);
// Если результат пуст
if (count($result) == 0)
// -- возвращаю null
return null;
// Возвращаю результат
return $result[0];
}
/**
* Получает колонку в массиве данных.
*
* @param string $column Имя колонки.
* @param callable|null $wherePredicate Условие выборки <code>fn (mixed $item): bool</code>, которое проверяет,
* подходит элемент или нет.
*
* @return array Ассоциированный массив с результатом выборки.
*/
public function GetColumn (string $column, ?callable $wherePredicate = null): array
{
return $this->GetColumnCallback(fn ($item) => property_exists($item, $column) ? $item->$column : null,
$wherePredicate);
}
/**
* Получает колонку в массиве данных.
*
* @param callable $columnPredicate Функция <code>fn (mixed $item): mixed</code>, возвращающая значение элемента
* колонки.
* @param callable|null $wherePredicate Условие выборки <code>fn (mixed $item): bool</code>, которое проверяет,
* подходит элемент или нет.
*
* @return array Ассоциированный массив с результатом выборки.
*/
public function GetColumnCallback (callable $columnPredicate, ?callable $wherePredicate = null): array
{
// Создаю результат
$result = [];
// Прохожу по массиву
foreach ($this->Container as $item) {
// - пропускаю не объекты
if (!is_object($item))
continue;
// - пропускаю не удовлетворяющие условию
if ($wherePredicate !== null && !$wherePredicate($item))
continue;
// - добавляю значение свойства в результат
$result[] = $columnPredicate($item);
}
// Возвращаю результат
return $result;
}
/**
* Заменяет данные в строке\ массива.
*
* @param array $setItems Заменяемые элементы.
* @param callable $wherePredicate Условие выборки <code>fn (mixed $item): bool</code>, которое проверяет,
* подходит элемент или нет.
*
* @return bool Результат выполнения
*/
public function Update (array $setItems, callable $wherePredicate): bool
{
// Удаляю элементы
$result = $this->Delete($wherePredicate);
// Добавляю новые элементы
$this->AddRange($setItems);
// Возвращаю результат
return $result;
}
/**
* Удаляет строки по условию.
*
* @param callable|null $wherePredicate Условие выборки <code>fn (mixed $item): bool</code>, которое проверяет,
* подходит элемент или нет.
*
* @return bool Результат выполнения. Будет true, если все строки, удовлетворяющие условию удалены успешно,
* иначе false.
*/
public function Delete (?callable $wherePredicate = null): bool
{
// Задаю результат
$result = true;
// Получаю массив строк
$array = $this->GetRows($wherePredicate);
// Каждый элемент в этих строках
foreach ($array as $item) {
// - получаю его индекс в основном массиве
$key = array_search($item, $this->Container);
// - и если индекс найден
if ($key !== false) {
// -- удаляю элемент из основного массива
$resultArray = array_splice($this->Container, $key, 1);
// -- и если удаление прошло успешно, то будет true
$result = $result && count($resultArray) > 0;
}
}
// Возвращаю результат
return $result;
}
/**
* Проверяет, существует ли объект в массиве.
*
* @param callable|null $where Условие выборки <code>fn (mixed $item): bool</code>, которое проверяет, подходит ли
* объект или нет. Может принимать вместо замыкания null, тогда вернёт false. По умолчанию null.
*
* @return bool Результат проверки
*/
public function IsExist (?callable $where = null): bool
{
// Если условие не задано
if ($where === null || !is_callable($where))
// - то возвращаем false
return false;
// Вывожу результат
return $this->Count($where) > 0;
}
/**
* Считает количество объектов в массиве, удовлетворяющих условию.
*
* @param callable|null $predicate Функция, возвращающая bool: true, если объект удовлетворяет условию, false, если
* не удовлетворяет. Параметром является объект массива. Вместо функции можно передать null, тогда результатом
* будет общее количество объектов в массиве. По умолчанию, null.
*
* @return int Количество объектов, удовлетворяющих условию
*/
public function Count (?callable $predicate = null): int
{
// Если условие не задано
if ($predicate === null || !is_callable($predicate))
// - то возвращаем общее количество объектов
return count($this->Container);
// Создаём результирующее число
$result = 0;
// Проходим по массиву
foreach ($this->Container as $item) {
// - пропускаем не объекты
if (!is_object($item))
continue;
// - если элемент удовлетворяет условию
if ($predicate($item))
// -- добавляем счётчик
$result++;
}
// Возвращаем результат
return $result;
}
/**
* Возвращает первый элемент массива или значение по умолчанию.
*
* @param mixed|null $default Значение по умолчанию. По умолчанию, null.
*
* @return mixed|null Возвращает первый элемент массива или значение по умолчанию.
*/
public function First (mixed $default = null): mixed
{
// Получение первого элемента
$firstElement = reset($this->Container);
// Проверяем получение
if ($firstElement === false)
// - возвращаем значение по умолчанию
return $default;
// Возвращаем первый элемент
return $firstElement;
}
/**
* Возвращает последний элемент массива или значение по умолчанию.
*
* @param mixed|null $default Значение по умолчанию. По умолчанию, null.
*
* @return mixed|null Возвращает последний элемент массива или значение по умолчанию.
*/
public function Last (mixed $default = null): mixed
{
// Получение последнего элемента
$lastElement = end($this->Container);
// Проверяем получение
if ($lastElement === false)
// - возвращаем значение по умолчанию
return $default;
// Возвращаем первый элемент
return $lastElement;
}
/**
* Пропускает первые $count элементов массива. Возвращает новый массив.
*
* ВНИМАНИЕ: рекомендуется использовать ТОЛЬКО на отсортированных массивах.
*
* @param int $count Количество элементов, которые необходимо обрезать с начала массива.
*
* @return ObjectArray Возвращает новый массив, состоящий из элементов, начиная с $count + 1 элемента.
*/
public function Skip (int $count): ObjectArray
{
return new ObjectArray(array_slice($this->Container, $count));
}
/**
* Получает первые $count элементов массива. Возвращает новый массив.
*
* ВНИМАНИЕ: рекомендуется использовать ТОЛЬКО на отсортированных массивах.
*
* @param int $count Количество элементов, которые необходимо получить с начала массива.
*
* @return ObjectArray Возвращает новый массив, состоящий из первых $count элементов старого массива.
*/
public function Take (int $count): ObjectArray
{
return new ObjectArray(array_slice($this->Container, 0, $count));
}
/**
* Совмещает в себе две функции, которые одновременно применяет к массиву: Skip ($startFrom) и Take ($count).
* Возвращает новый массив.
*
* ВНИМАНИЕ: рекомендуется использовать ТОЛЬКО на отсортированных массивах.
*
* @param int $startFrom Начальный индекс массива, с которого нужно получить.
* @param int $count Количество элементов, которые необходимо получить.
*
* @return ObjectArray Возвращает новый массив, состоящий из $count элементов старого массива, начиная с индекса
* $startFrom.
*/
public function SkipAndTake (int $startFrom, int $count): ObjectArray
{
return new ObjectArray(array_slice($this->Container, $startFrom, $count));
}
}