fn = array_shift($params); $this->params = $params; } function apply() { $params = func_get_args(); array_splice($params, count($params), 0, $this->params); return call_user_func_array($this->fn, $params); } } class __left { protected $params; protected $fn; public function __construct($params) { $this->fn = array_shift($params); $this->params = $params; } function apply() { $params = func_get_args(); array_splice ($params, 0, 0, $this->params); return call_user_func_array ($this->fn, $params); } } define('__', '_ARGUMENT_PLACE_'); class __partial { protected $params; protected $fn; public function __construct($params) { $this->fn = array_shift($params); $this->params = $params; } function apply() { $params = func_get_args(); $result = array(); for($i = 0, $j = 0; $i < count($this->params); $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); } function apply () { $params = func_get_args (); $result = call_user_func_array($this->fns[0], $params); for ($i = 1; $i < count($this->fns); $i++) { $result = call_user_func($this->fns[$i], $result); } return $result; } } class Functions { static function partial() { $closure = new __partial(func_get_args()); return array($closure, 'apply'); } /** * Композиция функций * @param mixed $a * @param mixed $b * * @return array[int]mixed */ static function compose() { $closure = new __compose(func_get_args()); return array($closure, 'apply'); } /** * Карирование справа * * @return array[int]mixed */ static function rcurry($_rest) { $closure = new __right(func_get_args ()); return array($closure, 'apply'); } /** * Карирование слева * * @return array[int]mixed */ static function lcurry($_rest) { $closure = new __left(func_get_args ()); return array($closure, 'apply'); } /** * Разделение массива на два по условию * @param mixed $pred Условие по которому разделяется массив * @param array $lst * * @return array[int]mixed */ static function partition($pred, $lst) { $left = array (); $right = array (); foreach ($lst as $n) { if (call_user_func($pred, $n) !== false) { $left [] = $n; } else { $right [] = $n; } } return array ($left, $right); } /** * @param array $value * @param string $name * * @return mixed */ static function __key($value, $name) { return $value[$name]; } static function identity($value) { return $value; } /** * @param array $a * @param array $b * @param $key * * @return int */ static function __cmp($a, $b, $key) { if ($a[$key] == $b[$key]) { return 0; } return ($a[$key] > $b[$key]) ? -1 : 1; } static function __cmp_less($a, $b, $key) { if ($a[$key] == $b[$key]) { return 0; } return ($a[$key] < $b[$key]) ? -1 : 1; } // Сравнение по ключу массиве static function __index($n, $key, $row) { return ($row[$key] == $n); } static function __div($x, $y) { return $x / $y; } static function __self($name, $o) { return call_user_func(array($o, $name)); } static function concat(/* $args ...*/) { $args = func_get_args(); return implode("", $args); } static function __empty($x) { return empty($x); } // Отрицание static function __not($x) { return !$x; } // Не равно static function __neq($x, $y) { return $x != $y; } // Равно static function __eq($x, $y) { return $x == $y; } /** * Извлекает из многомерого массива значения с определенным ключом * @example key_values('a', array(1 => array('a' => 1, 'b' => 2))) => array(1) * * @return mixed */ static function key_values($key, /*array|ArrayIterator*/ $array) { $result = array(); foreach($array as $item) { $result[] = $item[$key]; } return $result; } static function key_values_object($key, /*array|ArrayIterator*/ $array) { $result = array(); foreach($array as $item) { $result[] = $item->{$key}; } return $result; } static function assoc_key_values($key, $value, $array) { $result = array(); foreach ($array as $item) { $result[$item[$key]] = $item[$value]; } return $result; } static function assoc_key($key, $array) { $result = array(); foreach ($array as $item) { $result[$item[$key]] = $item; } return $result; } static function _get($key, /*.any.*/$value, /*.array.*/$array) { foreach ($array as $item) { if ($item[$key] == $value) return $item; } return null; } static function _get_key($key, $value, $array) { foreach ($array as $name => $item) { if ($item[$key] == $value) return $name; } return null; } /** * Логическа операция && ко всем элементам массива * @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 mixed $callback * * @return mixed */ static function some(array $array, $callback) { assert(is_callable($callback)); foreach ($array as $key => $value) { if (call_user_func($callback, $value) === true) { return $key; } } return false; } static function span($length, array $array) { assert(is_int($length)); $result = array(); for($i = 0; $i < count($array); $i += $length) { $result [] = array_slice($array, $i, $length); } return $result; } static function array_ref($data, $n) { return $data[$n]; } static function call() { $args = func_get_args(); $name = array_shift($args); return call_user_func_array($name, $args); } /** * Поиск элемента в массиве * @param function $cb сравнение с элементом массива * @param array $hs массив в котором ищется значение * * @return int|string ключ найденого элемента в массиве */ static function array_usearch($cb, array $hs, $strict = false) { foreach($hs as $key => $value) if (call_user_func_array($cb, array($value, $key, $strict))) return $key; } /** * Выбирает все сроки из таблицы с уникальными значениями ключа * @param $name Имя ключа * @param $table Двухмерный массив * @example * key_unique_values ('name', array (array ('name' => 1), array ('name' => 2), array ('name' => 1))) => array (1, 2) * @end example */ static function key_unique_values ($name, $table) { // Ищем уникальные значения для заданного ключа $keys = array (); foreach ($table as $row) { if (!in_array ($row[$name], $keys)) $keys[] = $row[$name]; } return $keys; } /** * Сортировка двумерного массива по заданному ключу * @param $array Массив * @param $key Имя ключа по значению которого будет идти сравнение * @return Отсортированный массив */ static function sortOn($array, $key, $fn = '__cmp') { usort ($array, Functions::rcurry($fn, $key)); //usort ($array, create_function ('$x,$y', 'return __cmp ($x, $y, "'.$key.'");')); return $array; } /** * Преобразует ключи элементов для многомерного массива * @return mixed */ static function hash_key ($key_name,/*. array .*/ $array) { $result = array(); foreach($array as $value) { $result[$value[$key_name]] = $value; } return $result; } }