479 lines
12 KiB
PHP
479 lines
12 KiB
PHP
<?php
|
||
|
||
namespace ctiso;
|
||
|
||
/**
|
||
* Эмуляция каррированой функции
|
||
*/
|
||
class right {
|
||
/** @var array<mixed> */
|
||
protected $params;
|
||
/** @var callable */
|
||
protected $fn;
|
||
|
||
/**
|
||
* @param array $params
|
||
*/
|
||
public function __construct($params) {
|
||
$this->fn = array_shift($params);
|
||
$this->params = $params;
|
||
}
|
||
|
||
/**
|
||
* Применение функции
|
||
* @param mixed ...$params
|
||
* @return mixed
|
||
*/
|
||
function apply(...$params) {
|
||
array_splice($params, count($params), 0, $this->params);
|
||
return call_user_func_array($this->fn, $params);
|
||
}
|
||
}
|
||
|
||
class left {
|
||
/** @var array<mixed> */
|
||
protected $params;
|
||
/** @var callable */
|
||
protected $fn;
|
||
|
||
/**
|
||
* @param array $params
|
||
*/
|
||
public function __construct($params) {
|
||
$this->fn = array_shift($params);
|
||
$this->params = $params;
|
||
}
|
||
|
||
/**
|
||
* Применение функции
|
||
* @param mixed ...$params
|
||
* @return mixed
|
||
*/
|
||
function apply(...$params) {
|
||
array_splice ($params, 0, 0, $this->params);
|
||
return call_user_func_array ($this->fn, $params);
|
||
}
|
||
}
|
||
|
||
define('__', '_ARGUMENT_PLACE_');
|
||
class partial {
|
||
/** @var array<mixed> */
|
||
protected $params;
|
||
/** @var callable */
|
||
protected $fn;
|
||
|
||
/**
|
||
* @param array $params
|
||
*/
|
||
public function __construct($params) {
|
||
$this->fn = array_shift($params);
|
||
$this->params = $params;
|
||
}
|
||
|
||
/**
|
||
* Применение функции
|
||
* @param mixed ...$params
|
||
* @return mixed
|
||
*/
|
||
function apply(...$params) {
|
||
$result = [];
|
||
$count = count($this->params);
|
||
for($i = 0, $j = 0; $i < $count; $i++) {
|
||
if ($this->params[$i] == __) {
|
||
$result [] = $params[$j];
|
||
$j++;
|
||
} else {
|
||
$result [] = $this->params[$i];
|
||
}
|
||
}
|
||
return call_user_func_array ($this->fn, $result);
|
||
}
|
||
}
|
||
|
||
/**
|
||
* Композиция функций
|
||
*/
|
||
class compose {
|
||
protected $fns;
|
||
function __construct($list) {
|
||
$this->fns = array_reverse($list);
|
||
}
|
||
|
||
/**
|
||
* Применение функций
|
||
* @param mixed ...$params
|
||
* @return mixed
|
||
*/
|
||
function apply (...$params) {
|
||
$result = call_user_func_array($this->fns[0], $params);
|
||
$count = count($this->fns);
|
||
for ($i = 1; $i < $count; $i++) {
|
||
$result = call_user_func($this->fns[$i], $result);
|
||
}
|
||
return $result;
|
||
}
|
||
}
|
||
|
||
class Functions {
|
||
|
||
/**
|
||
* Частичное применение функции
|
||
* @param mixed ...$args
|
||
* @return mixed
|
||
*/
|
||
static function partial(...$args) {
|
||
$closure = new partial($args);
|
||
return [$closure, 'apply'];
|
||
}
|
||
|
||
|
||
/**
|
||
* Композиция функций
|
||
* @param mixed ...$args
|
||
* @return mixed
|
||
*/
|
||
static function compose(...$args) {
|
||
$closure = new compose($args);
|
||
return [$closure, 'apply'];
|
||
}
|
||
|
||
/**
|
||
* Карирование справа
|
||
* @param mixed ...$args
|
||
* @return mixed
|
||
*/
|
||
static function rcurry(...$args) {
|
||
$closure = new right($args);
|
||
return [$closure, 'apply'];
|
||
}
|
||
|
||
/**
|
||
* Карирование слева
|
||
* @param mixed ...$args
|
||
* @return mixed
|
||
*/
|
||
static function lcurry(...$args) {
|
||
$closure = new left($args);
|
||
return [$closure, 'apply'];
|
||
}
|
||
|
||
/**
|
||
* Разделение массива на два по условию
|
||
* @param mixed $pred Условие по которому разделяется массив
|
||
* @param array $lst
|
||
*
|
||
* @return mixed
|
||
*/
|
||
static function partition($pred, $lst) {
|
||
$left = [];
|
||
$right = [];
|
||
foreach ($lst as $n) {
|
||
if (call_user_func($pred, $n) !== false) {
|
||
$left [] = $n;
|
||
} else {
|
||
$right [] = $n;
|
||
}
|
||
}
|
||
return [$left, $right];
|
||
}
|
||
|
||
/**
|
||
* @deprecated
|
||
* @param array<string, mixed> $value
|
||
* @param string $name
|
||
*
|
||
* @return mixed
|
||
*/
|
||
static function __key($value, $name) {
|
||
return $value[$name];
|
||
}
|
||
|
||
/**
|
||
* @deprecated
|
||
* @param mixed $value
|
||
*
|
||
* @return mixed
|
||
*/
|
||
static function identity($value) {
|
||
return $value;
|
||
}
|
||
|
||
/**
|
||
* @deprecated use fn and <=> operator
|
||
* @param array $a
|
||
* @param array $b
|
||
* @param string|int $key
|
||
*
|
||
* @return int
|
||
*/
|
||
static function __cmp($a, $b, $key) {
|
||
if ($a[$key] == $b[$key]) {
|
||
return 0;
|
||
}
|
||
return ($a[$key] > $b[$key]) ? -1 : 1;
|
||
}
|
||
|
||
/**
|
||
* @deprecated use fn and <=> operator
|
||
* @param array $a
|
||
* @param array $b
|
||
* @param string|int $key
|
||
*
|
||
* @return int
|
||
*/
|
||
static function __cmp_less($a, $b, $key) {
|
||
if ($a[$key] == $b[$key]) {
|
||
return 0;
|
||
}
|
||
return ($a[$key] < $b[$key]) ? -1 : 1;
|
||
}
|
||
|
||
/**
|
||
* @deprecated
|
||
* @param string $name Метод
|
||
* @param object $o
|
||
*
|
||
* @return mixed
|
||
*/
|
||
static function __self($name, $o) {
|
||
return call_user_func([$o, $name]);
|
||
}
|
||
|
||
/**
|
||
* @param string ...$args
|
||
* @return string
|
||
*/
|
||
static function concat(...$args) {
|
||
return implode("", $args);
|
||
}
|
||
|
||
/**
|
||
* @param mixed $x
|
||
* @return bool
|
||
*/
|
||
static function __empty($x) {
|
||
return empty($x);
|
||
}
|
||
|
||
/**
|
||
* Извлекает из многомерого массива значения с определенным ключом
|
||
* @example key_values('a', array(1 => array('a' => 1, 'b' => 2))) => array(1)
|
||
*
|
||
* @param string $key
|
||
* @param list<array>|\ArrayIterator $array
|
||
* @return mixed
|
||
*/
|
||
static function key_values($key, $array) {
|
||
$result = [];
|
||
|
||
foreach($array as $item) {
|
||
$result[] = $item[$key];
|
||
}
|
||
return $result;
|
||
}
|
||
|
||
/**
|
||
* @param string $key
|
||
* @param list<object>|\ArrayIterator $array
|
||
*/
|
||
static function key_values_object($key, $array) {
|
||
$result = [];
|
||
|
||
foreach($array as $item) {
|
||
$result[] = $item->{$key};
|
||
}
|
||
return $result;
|
||
}
|
||
|
||
/**
|
||
* @param string $key
|
||
* @param string $value
|
||
* @param list<array<string, mixed>>|\ArrayIterator $array
|
||
* @return array<string, mixed>
|
||
*/
|
||
static function assoc_key_values($key, $value, $array) {
|
||
$result = [];
|
||
foreach ($array as $item) {
|
||
$result[$item[$key]] = $item[$value];
|
||
}
|
||
return $result;
|
||
}
|
||
|
||
/**
|
||
* @param string $key
|
||
* @param list<array<string, mixed>>|\ArrayIterator $array
|
||
* @return array<string, mixed>
|
||
*/
|
||
static function assoc_key($key, $array) {
|
||
$result = [];
|
||
foreach ($array as $item) {
|
||
$result[$item[$key]] = $item;
|
||
}
|
||
return $result;
|
||
}
|
||
|
||
/**
|
||
* Возвращает значение по ключу
|
||
* @param string $key
|
||
* @param mixed $value
|
||
* @param array $array
|
||
* @return mixed
|
||
*/
|
||
static function _get($key, $value, $array) {
|
||
foreach ($array as $item) {
|
||
if ($item[$key] == $value) {
|
||
return $item;
|
||
}
|
||
}
|
||
return null;
|
||
}
|
||
|
||
/**
|
||
* Возвращает ключ по значению
|
||
* @param string $key
|
||
* @param mixed $value
|
||
* @param array $array
|
||
* @return mixed
|
||
*/
|
||
static function _get_key($key, $value, $array) {
|
||
foreach ($array as $name => $item) {
|
||
if ($item[$key] == $value) {
|
||
return $name;
|
||
}
|
||
}
|
||
return null;
|
||
}
|
||
|
||
|
||
/**
|
||
* Логическа операция && ко всем элементам массива
|
||
* @param array<mixed> $array Массив
|
||
* @param callable $callback Функция
|
||
* @return bool
|
||
*/
|
||
static function every(array $array, $callback) {
|
||
foreach ($array as $value) {
|
||
if (call_user_func($callback, $value) === false) {
|
||
return false;
|
||
}
|
||
}
|
||
return true;
|
||
}
|
||
|
||
/**
|
||
* Логическа операция || ко всем элементам массива
|
||
* @param array<mixed> $array Массив
|
||
* @param callable $callback Функция
|
||
* @return mixed
|
||
*/
|
||
static function some(array $array, callable $callback) {
|
||
foreach ($array as $key => $value) {
|
||
if (call_user_func($callback, $value) === true) {
|
||
return $key;
|
||
}
|
||
}
|
||
return false;
|
||
}
|
||
|
||
/**
|
||
* Разбивает массив на массивы определенной длины
|
||
* @template T
|
||
* @param int $length Длина массива
|
||
* @param T[] $array Массив
|
||
* @return T[][]
|
||
*/
|
||
static function span(int $length, array $array) {
|
||
$result = [];
|
||
$count = count($array);
|
||
for($i = 0; $i < $count; $i += $length) {
|
||
$result [] = array_slice($array, $i, $length);
|
||
}
|
||
return $result;
|
||
}
|
||
|
||
/**
|
||
* Возвращает значение массива
|
||
* @param array $data Массив
|
||
* @param string|int $n Ключ
|
||
* @return mixed
|
||
*/
|
||
static function array_ref(array $data, string|int $n) {
|
||
return $data[$n];
|
||
}
|
||
|
||
/**
|
||
* Вызывает функцию с аргументами
|
||
* @param mixed ...$args Аргументы
|
||
* @return mixed
|
||
*/
|
||
static function call(...$args) {
|
||
$name = array_shift($args);
|
||
return call_user_func_array($name, $args);
|
||
}
|
||
|
||
/**
|
||
* Поиск элемента в массиве
|
||
* @param callable $cb сравнение с элементом массива
|
||
* @param array $hs массив в котором ищется значение
|
||
*
|
||
* @return int|string|null ключ найденого элемента в массиве
|
||
*/
|
||
static function array_usearch($cb, array $hs, $strict = false) {
|
||
foreach($hs as $key => $value) {
|
||
if (call_user_func_array($cb, [$value, $key, $strict])) {
|
||
return $key;
|
||
}
|
||
}
|
||
return null;
|
||
}
|
||
|
||
/**
|
||
* Выбирает все сроки из таблицы с уникальными значениями ключа
|
||
* @example
|
||
* key_unique_values ('name', array (array ('name' => 1), array ('name' => 2), array ('name' => 1)))
|
||
* => array (1, 2)
|
||
*
|
||
* @param string $name Имя ключа
|
||
* @param array $table Двухмерный массив
|
||
* @return array Массив с уникальными значениями ключа
|
||
*/
|
||
static function key_unique_values ($name, $table) {
|
||
// Ищем уникальные значения для заданного ключа
|
||
$keys = [];
|
||
foreach ($table as $row) {
|
||
if (!in_array ($row[$name], $keys)) {
|
||
$keys[] = $row[$name];
|
||
}
|
||
}
|
||
return $keys;
|
||
}
|
||
|
||
/**
|
||
* Сортировка двумерного массива по заданному ключу
|
||
* @param array $array Массив
|
||
* @param string $key Имя ключа по значению которого будет идти сравнение
|
||
* @param callable $fn Функция сравнения
|
||
* @return array Отсортированный массив
|
||
*/
|
||
static function sortOn($array, $key, $fn = '\\ctiso\\Functions::__cmp') {
|
||
usort ($array, Functions::rcurry($fn, $key));
|
||
//usort ($array, create_function ('$x,$y', 'return __cmp ($x, $y, "'.$key.'");'));
|
||
return $array;
|
||
}
|
||
|
||
/**
|
||
* Преобразует ключи элементов для многомерного массива
|
||
* @param string $key_name Имя ключа
|
||
* @param array $array Многомерный массив
|
||
* @return mixed
|
||
*/
|
||
static function hash_key ($key_name, $array) {
|
||
$result = [];
|
||
|
||
foreach($array as $value) {
|
||
$result[$value[$key_name]] = $value;
|
||
}
|
||
return $result;
|
||
}
|
||
}
|
||
|