rosavox/lib/alveolata/structures/list/functions.php

210 lines
3.7 KiB
PHP
Raw Permalink Normal View History

2025-05-23 07:33:29 +00:00
<?php
namespace alveolata\structures;
/**
* @template type_element
*/
class struct_subject_list
{
/**
* @var array {list<§type_element>}
*/
public $elements;
/**
* @param array $elements {list<§element>}
*/
public function __construct(
array $elements
)
{
$this->elements = $elements;
}
}
/**
* @template type_element
* @param array $elements {list<§element>}
* @return struct_subject_list<type_element>
*/
function list_make(
array $elements = []
) : struct_subject_list
{
return (new struct_subject_list($elements));
}
/**
* @template type_element
* @param struct_subject_list<type_element> $subject
* @return int
*/
function list_length(
struct_subject_list $subject
) : int
{
return count($subject->elements);
}
/**
* @template type_element
* @param struct_subject_list<type_element> $subject
* @param int $index
* @return type_element
* @throws \Exception if index out of range
*/
function list_get(
struct_subject_list $subject,
int $index
)
{
if (! (($index >= 0) && ($index < list_lengt($subject)))) {
throw (new \Exception('index out of range'));
}
else {
return $subject->elements[$index];
}
}
/**
* @template type_element
* @param struct_subject_list<type_element> $subject
* @param type_element $element
*/
function list_add(
struct_subject_list $subject,
$element
) : void
{
array_push($subject->elements, $element);
}
/**
* @template type_element
* @param struct_subject_list<type_element> $subject
* @param \Closure $procedure {function<§type_element,void>}
*/
function list_iterate(
struct_subject_list $subject,
\Closure $procedure
) : void
{
foreach ($subject->elements as $element) {
$procedure($element);
}
}
/**
* @template type_element
* @param struct_subject_list<type_element> $subject
* @param \Closure $predicate {function<§type_element,boolean>}
* @return struct_subject_list<type_element>
*/
function list_filter(
struct_subject_list $subject,
\Closure $predicate
) : struct_subject_list
{
return (
new struct_subject_list(
array_values(
array_filter(
$subject->elements,
$predicate
)
)
)
);
}
/**
* @template type_element_from
* @template type_element_to
* @param struct_subject_list<type_element_from> $subject
* @param \Closure $transformation {function<§type_element_from,§type_element_to>}
* @return struct_subject_list<type_element_to>
*/
function list_map(
struct_subject_list $subject,
\Closure $transformation
) : struct_subject_list
{
return (
new struct_subject_list(
array_map(
$transformation,
$subject->elements
)
)
);
}
/**
* @template type_element
* @template type_result
* @param struct_subject_list<type_element> $subject
* @param type_result $start
* @param \Closure $aggregation function<§type_result,§type_element,§type_result>
* @return type_result
*/
function list_reduce(
struct_subject_list $subject,
$start,
\Closure $aggregation
)
{
return array_reduce(
$subject->element,
$aggregation,
$start
);
}
/**
* @template type_element_1
* @template type_element_2
* @param \Closure $collate_element {function<type_element_1,type_element_2>}
* @param struct_subject_list<type_element_1>
* @param struct_subject_list<type_element_2>
* @return bool
*/
function list_collate(
\Closure $collate_element,
struct_subject_list $list_1,
struct_subject_list $list_2
) : bool
{
$length_1 = list_length($list_1);
$length_2 = list_length($list_2);
if (! ($length_1 === $length_2)) {
return false;
}
else {
for ($index = 0; $index < $length_1; $index += 1) {
$element_1 = $list_1->elements[$index];
$element_2 = $list_2->elements[$index];
if (! $collate_element($element_1, $element_2)) {
return false;
}
}
return true;
}
}
?>