phplibrary/src/Functions.php
Фёдор Подлеснов db7b5c7d25 Поправил типы
2018-02-09 12:02:35 +03:00

380 lines
9.9 KiB
PHP
Raw Blame History

This file contains ambiguous Unicode characters

This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.

<?php
/**
* Функциональное программирование в PHP
* package functional
*/
/**
* Эмуляция каррированой функции
*/
class __right {
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, 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 = 'Functions::__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;
}
}