php_components_pack/sources/traits/ObjectArray/ObjectArrayLINQTrait.php
babaev-an c32c8643ee 20250205
+ [ObjectArray]: Добавлена функция GetColumnCallback для лучшего получения колонки.
2025-02-05 18:54:56 +03:00

295 lines
13 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);
// Добавляю новые элементы
foreach ($setItems as $item)
$this->Container[] = $item;
// Возвращаю результат
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;
}
}