intégrer les méthodes de Cursor et KeyAccess
This commit is contained in:
parent
dd3006e05d
commit
8e7e59cc42
108
php/src/A.php
108
php/src/A.php
@ -1,6 +1,7 @@
|
||||
<?php
|
||||
namespace nulib;
|
||||
|
||||
use nulib\php\func;
|
||||
use Traversable;
|
||||
|
||||
/**
|
||||
@ -232,4 +233,111 @@ class A {
|
||||
if ($assoc) uasort($array, cl::compare($keys));
|
||||
else usort($array, cl::compare($keys));
|
||||
}
|
||||
|
||||
#############################################################################
|
||||
|
||||
/**
|
||||
* s'assurer que $array est un tableau associatif, en remplaçant toutes les
|
||||
* clés numériques par la clé correspondante dans $key
|
||||
* <code>
|
||||
* $array = ["first", "second"]
|
||||
* A::ensure_assoc($array, ["a", "b"]);
|
||||
* // returns ["a" => "first", "b" => "second"]
|
||||
* </code>
|
||||
*/
|
||||
static final function ensure_assoc(?array &$array, array $keys, ?array $params=null): void {
|
||||
$prefix = $params["key_prefix"] ?? null;
|
||||
$suffix = $params["key_suffix"] ?? null;
|
||||
$index = 0;
|
||||
foreach ($keys as $key) {
|
||||
if ($prefix !== null || $suffix !== null) {
|
||||
$destKey = "$prefix$key$suffix";
|
||||
} else {
|
||||
# préserver les clés numériques
|
||||
$destKey = $key;
|
||||
}
|
||||
if ($array !== null && array_key_exists($destKey, $array)) continue;
|
||||
while (in_array($index, $keys, true)) {
|
||||
$index++;
|
||||
}
|
||||
if ($array !== null && array_key_exists($index, $array)) {
|
||||
$array[$destKey] = $array[$index];
|
||||
unset($array[$index]);
|
||||
$index++;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* s'assurer que $array contient toutes les clés de $defaults, avec la valeur
|
||||
* par défaut le cas échéant
|
||||
*
|
||||
* $missings est un tableau indiquant des valeurs qui si elles sont dans
|
||||
* $array, signifie que la clé correspondante doit être considérée comme
|
||||
* inexistante (et donc remplacée par la valeur de $defaults)
|
||||
*/
|
||||
static final function ensure_keys(?array &$array, array $defaults, ?array $missings=null, ?array $params=null): void {
|
||||
$keys = array_keys($defaults);
|
||||
$prefix = $params["key_prefix"] ?? null;
|
||||
$suffix = $params["key_suffix"] ?? null;
|
||||
foreach ($keys as $key) {
|
||||
$destKey = "$prefix$key$suffix";
|
||||
$haveMissing = $missings !== null && array_key_exists($key, $missings);
|
||||
if ($array === null || !array_key_exists($destKey, $array)) {
|
||||
$array[$destKey] = $defaults[$key];
|
||||
} elseif ($haveMissing && $array[$destKey] === $missings[$key]) {
|
||||
$array[$destKey] = $defaults[$key];
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* supprimer dans $array les clés dont les valeurs correspondent au tableau
|
||||
* $missings
|
||||
*/
|
||||
static final function delete_missings(?array &$array, array $missings, ?array $params=null): void {
|
||||
$prefix = $params["key_prefix"] ?? null;
|
||||
$suffix = $params["key_suffix"] ?? null;
|
||||
foreach ($missings as $key => $missing) {
|
||||
$destKey = "$prefix$key$suffix";
|
||||
if (array_key_exists($destKey, $array) && $array[$destKey] === $missing) {
|
||||
unset($array[$destKey]);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* s'assurer que les clés dans $array sont dans le même ordre que dans $keys
|
||||
*
|
||||
* les clés supplémentaires sont poussées à la fin du tableau
|
||||
*/
|
||||
static final function ensure_order(?array &$array, array $keys, ?array $params=null): void {
|
||||
if ($array === null) return;
|
||||
|
||||
$prefix = $params["key_prefix"] ?? null;
|
||||
$suffix = $params["key_suffix"] ?? null;
|
||||
if ($prefix !== null || $suffix !== null) {
|
||||
foreach ($keys as &$key) {
|
||||
$key = "$prefix$key$suffix";
|
||||
}; unset($key);
|
||||
}
|
||||
|
||||
$destKeys = array_keys($array);
|
||||
$keyCount = count($keys);
|
||||
if (array_slice($destKeys, 0, $keyCount) === $keys) {
|
||||
# si le tableau a déjà les bonnes clés dans le bon ordre, rien à faire
|
||||
return;
|
||||
}
|
||||
|
||||
$ordered = [];
|
||||
foreach ($keys as $key) {
|
||||
if (array_key_exists($key, $array)) {
|
||||
$ordered[$key] = $array[$key];
|
||||
unset($array[$key]);
|
||||
}
|
||||
}
|
||||
$preserveKeys = $params["preserve_keys"] ?? false;
|
||||
if ($preserveKeys) $array = cl::merge2($ordered, $array);
|
||||
else $array = array_merge($ordered, $array);
|
||||
}
|
||||
}
|
||||
|
@ -398,15 +398,86 @@ class cl {
|
||||
|
||||
#############################################################################
|
||||
|
||||
static final function map($func, ?iterable $array): array {
|
||||
$result = [];
|
||||
if ($array !== null) {
|
||||
$func = func::with($func);
|
||||
foreach ($array as $key => $value) {
|
||||
$result[$key] = $func->invoke([$value, $key]);
|
||||
/**
|
||||
* tester si $array satisfait les conditions de $filter
|
||||
* - $filter est un scalaire, le transformer en [$filter]
|
||||
* - sinon $filter doit être un tableau de scalaires
|
||||
*
|
||||
* les règles des conditions sont les suivantes:
|
||||
* - une valeur séquentielle $key est équivalente à la valeur associative
|
||||
* $key => true
|
||||
* - une valeur associative $key => bool indique que la clé correspondante ne
|
||||
* doit pas (resp. doit) exister selon que bool vaut false (resp. true)
|
||||
* - une valeur associative $key => $value indique que la clé correspondante
|
||||
* doit exiter avec la valeur spécifiée
|
||||
*/
|
||||
static final function filter(?array $array, $filter): bool {
|
||||
if ($filter === null) return false;
|
||||
if (!is_array($filter)) $filter = [$filter];
|
||||
if (!$filter) return false;
|
||||
|
||||
$index = 0;
|
||||
foreach ($filter as $key => $value) {
|
||||
if ($key === $index) {
|
||||
$index++;
|
||||
if ($array === null) return false;
|
||||
if (!array_key_exists($value, $array)) return false;
|
||||
} elseif (is_bool($value)) {
|
||||
if ($value) {
|
||||
if ($array === null || !array_key_exists($key, $array)) return false;
|
||||
} else {
|
||||
if ($array !== null && array_key_exists($key, $array)) return false;
|
||||
}
|
||||
} else {
|
||||
if ($array === null) return false;
|
||||
if (!array_key_exists($key, $array)) return false;
|
||||
if ($array[$key] !== $value) return false;
|
||||
}
|
||||
}
|
||||
return $result;
|
||||
return true;
|
||||
}
|
||||
|
||||
/**
|
||||
* mapper le tableau source $array selon les règles suivantes illustrées dans
|
||||
* l'exemple suivant:
|
||||
* si
|
||||
* $map = ["a", "b" => "x", "c" => function() { return "y"; }, "d" => null]
|
||||
* alors retourner le tableau
|
||||
* ["a" => $array["a"], "b" => $array["x"], "c" => "y", "d" => null]
|
||||
*
|
||||
* si une fonction est utilisée, sa signature est
|
||||
* <code>function(mixed $value, string|int $key, ?array $array)</code>
|
||||
*/
|
||||
static function map(?array $array, ?array $map): ?array {
|
||||
if ($map === null) return $array;
|
||||
$index = 0;
|
||||
$mapped = [];
|
||||
foreach ($map as $key => $value) {
|
||||
if ($key === $index) {
|
||||
$index++;
|
||||
if ($value === null) $mapped[] = null;
|
||||
else $mapped[$value] = cl::get($array, $value);
|
||||
} elseif (is_callable($value)) {
|
||||
$func = func::with($value);
|
||||
$value = cl::get($array, $key);
|
||||
$mapped[$key] = $func->invoke([$value, $key, $array]);
|
||||
} else {
|
||||
if ($value === null) $mapped[$key] = null;
|
||||
else $mapped[$key] = cl::get($array, $value);
|
||||
}
|
||||
}
|
||||
return $mapped;
|
||||
}
|
||||
|
||||
static final function mapf(?iterable $items, $func): array {
|
||||
$mapped = [];
|
||||
if ($items !== null) {
|
||||
$func = func::with($func);
|
||||
foreach ($items as $key => $item) {
|
||||
$mapped[$key] = $func->invoke([$item, $key, $items]);
|
||||
}
|
||||
}
|
||||
return $mapped;
|
||||
}
|
||||
|
||||
#############################################################################
|
||||
|
Loading…
x
Reference in New Issue
Block a user