[Д] [ObjectArray->Add] Функция добавляет объект в массив объектов, хранящийся в данном классе (аналогично добавлению элемента в массив с помощью []). [Д] [ObjectArray->AddRange] Функция добавляет массив объектов (или объекты, заданные с помощью array) в массив объектов, хранящийся в данном классе. [И] [ObjectArray->Update] Добавление с помощью foreach заменено на AddRange. [Д] [IDuplicated] Добавлен интерфейс реализации дублирования классов. [Д] [IStoredAtSQL] Добавлен интерфейс поддержки моделей и классов, реализующих хранение свойств в SQL базе данных.
381 lines
17 KiB
PHP
381 lines
17 KiB
PHP
<?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));
|
||
}
|
||
} |