x, [a => y]] devient [a => [x, y]] * * si $recursive==true, alors * - [a => [x, [y]]] devient [a => [x, y]] */ static final function flatten(?iterable $values, bool $recursive=true): array { $flattened = []; if ($values !== null) { $index = 0; foreach ($values as $key => $value) { if ($key === $index) { # valeurs séquentielles # elles ne sont jamais quotées $index++; if (is_iterable($value)) { $value = self::flatten($value); $index2 = 0; foreach ($value as $key2 => $value2) { if ($key2 === $index2) { # sequentiel $index2++; $flattened[] = $value2; } else { if (array_key_exists($key2, $flattened)) { $pvalue2 = $flattened[$key2]; $value2 = self::_merge($pvalue2, $value2); } $flattened[$key2] = $value2; } } } else { $flattened[] = self::_strval($value); } } else { # valeurs associatives # la valeur est quotée si elle n'est pas dans un tableau if (array_key_exists($key, $flattened)) { $value = self::_merge($flattened[$key], $value); } if ($recursive && is_array($value)) { $value = self::flatten($value, true); } $flattened[$key] = $value; } } } return $flattened; } /** méthode de convenance pour quoter puis applatir $vs */ static final function fq($vs): array { return self::flatten(self::q($vs)); } /** retourner la chaine correspondant au tableau $vs applati */ static final function string(iterable $vs): string { $pieces = []; foreach (c::flatten($vs) as $v) { if ($v instanceof IContent) { $pieces[] = self::string($v->getContent()); } elseif ($v instanceof IPrintable) { ob_start(null, 0, PHP_OUTPUT_HANDLER_STDFLAGS ^ PHP_OUTPUT_HANDLER_FLUSHABLE); $v->print(); $pieces[] = ob_get_clean(); } else { $pieces[] = $v; } } return implode("", $pieces); } }