wrappedArray(); if ($array === null || $array === false) $array = []; elseif ($array instanceof Traversable) $array = cl::all($array); else $array = [$array]; return false; } /** * s'assurer que $array est un array s'il est non null. retourner true si * $array n'a pas été modifié (s'il était déjà un array ou s'il valait null). */ static final function ensure_narray(&$array): bool { if ($array instanceof IArrayWrapper) $array = $array->wrappedArray(); if ($array === null || is_array($array)) return true; if ($array === false) $array = []; elseif ($array instanceof Traversable) $array = cl::all($array); else $array = [$array]; return false; } /** * s'assurer que $array est un tableau de $size éléments, en complétant avec * des occurrences de $default si nécessaire * * @return bool true si le tableau a été modifié, false sinon */ static final function ensure_size(?array &$array, int $size, $default=null): bool { $modified = false; if ($array === null) { $array = []; $modified = true; } if ($size < 0) return $modified; $count = count($array); if ($count == $size) return $modified; if ($count < $size) { # agrandir le tableau while ($count++ < $size) { $array[] = $default; } return true; } # rétrécir le tableau $tmparray = []; foreach ($array as $key => $value) { if ($size-- == 0) break; $tmparray[$key] = $value; } $array = $tmparray; return true; } static function merge(&$dest, ...$merges): void { self::ensure_narray($dest); $dest = cl::merge($dest, ...$merges); } static function merge2(&$dest, ...$merges): void { self::ensure_narray($dest); $dest = cl::merge2($dest, ...$merges); } static final function select(&$dest, ?array $mappings, bool $inverse=false): void { self::ensure_narray($dest); $dest = cl::select($dest, $mappings, $inverse); } static final function selectm(&$dest, ?array $mappings, ?array $merge=null): void { self::ensure_narray($dest); $dest = cl::selectm($dest, $mappings, $merge); } static final function mselect(&$dest, ?array $merge, ?array $mappings): void { self::ensure_narray($dest); $dest = cl::mselect($dest, $merge, $mappings); } static final function pselect(&$dest, ?array $pkeys): void { self::ensure_narray($dest); $dest = cl::pselect($dest, $pkeys); } static final function pselectm(&$dest, ?array $pkeys, ?array $merge=null): void { self::ensure_narray($dest); $dest = cl::pselectm($dest, $pkeys, $merge); } static final function mpselect(&$dest, ?array $merge, ?array $pkeys): void { self::ensure_narray($dest); $dest = cl::mpselect($dest, $merge, $pkeys); } static final function set_nn(&$dest, $key, $value) { self::ensure_narray($dest); if ($value !== null) { if ($key === null) $dest[] = $value; else $dest[$key] = $value; } return $value; } static final function append_nn(&$dest, $value) { return self::set_nn($dest, null, $value); } static final function set_nz(&$dest, $key, $value) { self::ensure_narray($dest); if ($value !== null && $value !== false) { if ($key === null) $dest[] = $value; else $dest[$key] = $value; } return $value; } static final function append_nz(&$dest, $value) { self::ensure_narray($dest); return self::set_nz($dest, null, $value); } static final function prepend_nn(&$dest, $value) { self::ensure_narray($dest); if ($value !== null) { if ($dest === null) $dest = []; array_unshift($dest, $value); } return $value; } static final function prepend_nz(&$dest, $value) { self::ensure_narray($dest); if ($value !== null && $value !== false) { if ($dest === null) $dest = []; array_unshift($dest, $value); } return $value; } static final function replace_nx(&$dest, $key, $value) { self::ensure_narray($dest); if ($dest !== null && !array_key_exists($key, $dest)) { return $dest[$key] = $value; } else { return $dest[$key] ?? null; } } static final function replace_n(&$dest, $key, $value) { self::ensure_narray($dest); $pvalue = $dest[$key] ?? null; if ($pvalue === null) $dest[$key] = $value; return $pvalue; } static final function replace_z(&$dest, $key, $value) { self::ensure_narray($dest); $pvalue = $dest[$key] ?? null; if ($pvalue === null || $pvalue === false) $dest[$key] = $value; return $pvalue; } static final function pop(&$dest, $key, $default=null) { if ($dest === null) return $default; self::ensure_narray($dest); if ($key === null) return array_pop($dest); $value = $dest[$key] ?? $default; unset($dest[$key]); return $value; } static final function popx(&$dest, ?array $keys): array { $values = []; if ($dest === null) return $values; self::ensure_narray($dest); if ($keys === null) return $values; foreach ($keys as $key) { $values[$key] = self::pop($dest, $key); } return $values; } static final function filter_if(&$dest, callable $cond): void { self::ensure_narray($dest); $dest = cl::filter_if($dest, $cond); } static final function filter_z($dest): void { self::filter_if($dest, [cv::class, "z"]);} static final function filter_nz($dest): void { self::filter_if($dest, [cv::class, "nz"]);} static final function filter_n($dest): void { self::filter_if($dest, [cv::class, "n"]);} static final function filter_nn($dest): void { self::filter_if($dest, [cv::class, "nn"]);} static final function filter_t($dest): void { self::filter_if($dest, [cv::class, "t"]);} static final function filter_f($dest): void { self::filter_if($dest, [cv::class, "f"]);} static final function filter_pt($dest): void { self::filter_if($dest, [cv::class, "pt"]);} static final function filter_pf($dest): void { self::filter_if($dest, [cv::class, "pf"]);} static final function filter_equals($dest, $value): void { self::filter_if($dest, cv::equals($value)); } static final function filter_not_equals($dest, $value): void { self::filter_if($dest, cv::not_equals($value)); } static final function filter_same($dest, $value): void { self::filter_if($dest, cv::same($value)); } static final function filter_not_same($dest, $value): void { self::filter_if($dest, cv::not_same($value)); } ############################################################################# static final function sort(?array &$array, int $flags=SORT_REGULAR, bool $assoc=false): void { if ($array === null) return; if ($assoc) asort($array, $flags); else sort($array, $flags); } static final function ksort(?array &$array, int $flags=SORT_REGULAR): void { if ($array === null) return; ksort($array, $flags); } static final function usort(?array &$array, array $keys, bool $assoc=false): void { if ($array === null) return; 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 * * $array = ["first", "second"] * A::ensure_assoc($array, ["a", "b"]); * // returns ["a" => "first", "b" => "second"] * */ 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); } }