phplibrary/src/Functions.php

386 lines
10 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
*/
/**
* Эмуляция каррированой функции
*/
namespace ctiso;
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();
$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);
}
function apply () {
$params = func_get_args ();
$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 {
static function partial($_rest) {
$closure = new partial(func_get_args());
return array($closure, 'apply');
}
/**
* Композиция функций
* @param array $_rest
* @return mixed
*/
static function compose($_rest) {
$closure = new compose(func_get_args());
return array($closure, 'apply');
}
/**
* Карирование справа
*
* @return mixed
*/
static function rcurry($_rest) {
$closure = new right(func_get_args ());
return array($closure, 'apply');
}
/**
* Карирование слева
*
* @return mixed
*/
static function lcurry($_rest) {
$closure = new left(func_get_args ());
return array($closure, 'apply');
}
/**
* Разделение массива на два по условию
* @param mixed $pred Условие по которому разделяется массив
* @param array $lst
*
* @return 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/*: array|ArrayIterator*/) {
$result = array();
foreach($array as $item) {
$result[] = $item[$key];
}
return $result;
}
static function key_values_object($key, $array/*: array|ArrayIterator*/) {
$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, $value/*: any*/, $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();
$count = count($array);
for($i = 0; $i < $count; $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 mixed $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, array($value, $key, $strict))) return $key;
}
return null;
}
/**
* Выбирает все сроки из таблицы с уникальными значениями ключа
* @param string $name Имя ключа
* @param array $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 $array Массив
* @param string $key Имя ключа по значению которого будет идти сравнение
* @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;
}
/**
* Преобразует ключи элементов для многомерного массива
* @return mixed
*/
static function hash_key ($key_name,$array/*: array */) {
$result = array();
foreach($array as $value) {
$result[$value[$key_name]] = $value;
}
return $result;
}
}