phplibrary/src/Functions.php

479 lines
12 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
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;
}
}