[Д] [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));
 | ||
|     }
 | ||
| } |