*/ 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 */ 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 */ 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 $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|\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|\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>|\ArrayIterator $array * @return array */ 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>|\ArrayIterator $array * @return array */ 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 $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 $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; } }