diff --git a/nur_src/v/bs3/vc/CTable.php b/nur_src/v/bs3/vc/CTable.php index 4f66fce..2fa6f90 100644 --- a/nur_src/v/bs3/vc/CTable.php +++ b/nur_src/v/bs3/vc/CTable.php @@ -12,6 +12,7 @@ use nur\data\types\md_utils; use nur\data\types\Metadata; use nur\func; use nur\iter; +use nur\sery\cl; use nur\SL; use nur\v\base\ComponentPrintable; use nur\v\v; @@ -78,7 +79,7 @@ class CTable extends ComponentPrintable implements IParametrable { "rows" => ["?iterable", null, "source des lignes à afficher"], "filter_func" => ["?callable", null, "fonction permettant de filter les éléments à afficher"], "map_func" => ["?callable", null, "fonction permettant de mapper les éléments"], - #XXX ajouter "map" qui prend directement un tableau comme celui retourné par map_func() + "map" => ["?array", null, "tableau permettant de sélectionner les éléments"], "cols" => ["?array", null, "colonnes à extraire et à afficher"], "exclude_cols" => ["?array", null, "colonnes à exclure de la liste calculée automatiquement"], "add_cols" => ["?array", null, "colonnes à ajouter à la liste calculée automatiquement"], @@ -138,6 +139,9 @@ class CTable extends ComponentPrintable implements IParametrable { else $this->mapCtx = func::_prepare($mapFunc); } + /** @var ?array */ + protected $ppMap; + protected $ppCols; protected $ppExcludeCols; @@ -357,7 +361,8 @@ class CTable extends ComponentPrintable implements IParametrable { protected function nextRow(): ?array { $filterCtx = $this->filterCtx; $mapCtx = $this->mapCtx; - $row = $this->_currentRow($this->rowKey); + $map = $this->ppMap; + $row = $this->rawRow; if ($filterCtx !== null) { if (!func::_call($filterCtx, [$row, $this->rowKey, $this->rowIndex])) return null; } @@ -365,13 +370,17 @@ class CTable extends ComponentPrintable implements IParametrable { # si la valeur est séquentielle, c'est une clé dans $row # si la valeur est associative et que c'est une fonction, elle est appelée # avec la valeur - $result = func::_call($mapCtx, [$row, $this->rowKey, $this->rowIndex]); + $map = func::_call($mapCtx, [$row, $this->rowKey, $this->rowIndex]); + } + if ($map !== null) { + $row = $this->ensureArray($row); $index = 0; $mapped = []; - foreach ($result as $key => $value) { + foreach ($map as $key => $value) { if ($key === $index) { $index++; - $mapped[$value] = A::get($row, $value); + if ($value === null) $mapped[] = null; + else $mapped[$value] = A::get($row, $value); } elseif (is_callable($value)) { $mapped[$key] = func::call($value, A::get($row, $key), $key, $row, $this->rowKey, $this->rowIndex); } else { @@ -441,8 +450,9 @@ class CTable extends ComponentPrintable implements IParametrable { $this->rowIndex = 0; $haveRows = false; while ($this->_validRow()) { - $this->origRow = $this->nextRow(); + $this->rawRow = $this->_currentRow($this->rowKey);; try { + $this->origRow = $this->nextRow(); if ($this->origRow === null) continue; $skipRow = false; @@ -557,10 +567,13 @@ class CTable extends ComponentPrintable implements IParametrable { /** @var string|int clé de la ligne courante */ protected $rowKey; - /** @var array la ligne avant sa "cuisine" */ + /** @var array la ligne originale, avant le mapping */ + protected $rawRow; + + /** @var array la ligne mappée avant sa "cuisine" */ protected $origRow; - /** @var array */ + /** @var array la ligne cuisinée */ protected $row; /** contenu à afficher avant la ligne */ diff --git a/src/cl.php b/src/cl.php index 9a6e716..3b557e2 100644 --- a/src/cl.php +++ b/src/cl.php @@ -136,50 +136,60 @@ class cl { * retourner un tableau construit à partir des clés de $keys * - [$to => $from] --> $dest[$to] = self::get($array, $from) * - [$to => null] --> $dest[$to] = null + * - [$to => false] --> NOP * - [$to] --> $dest[$to] = self::get($array, $to) - * - [null] --> NOP + * - [null] --> $dest[] = null + * - [false] --> NOP * * Si $inverse===true, le mapping est inversé: * - [$to => $from] --> $dest[$from] = self::get($array, $to) * - [$to => null] --> $dest[$to] = self::get($array, $to) + * - [$to => false] --> NOP * - [$to] --> $dest[$to] = self::get($array, $to) - * - [null] --> NOP + * - [null] --> NOP (XXX que faire dans ce cas?) + * - [false] --> NOP * * notez que l'ordre est inversé par rapport à {@link self::rekey()} qui * attend des mappings [$from => $to], alors que cette méthode attend des * mappings [$to => $from] */ static final function select($array, ?array $mappings, bool $inverse=false): array { - $selected = []; + $dest = []; $index = 0; - if ($inverse) { + if (!$inverse) { foreach ($mappings as $to => $from) { if ($to === $index) { $index++; $to = $from; - if ($to === null) continue; - $selected[$to] = self::get($array, $to); + if ($to === false) continue; + elseif ($to === null) $dest[] = null; + else $dest[$to] = self::get($array, $to); + } elseif ($from === false) { + continue; } elseif ($from === null) { - $selected[$to] = self::pget($array, $to); + $dest[$to] = null; } else { - $selected[$from] = self::pget($array, $to); + $dest[$to] = self::get($array, $from); } } } else { foreach ($mappings as $to => $from) { if ($to === $index) { $index++; - if ($from === null) continue; - $value = self::get($array, $from); $to = $from; + if ($to === false) continue; + elseif ($to === null) continue; + else $dest[$to] = self::get($array, $to); + } elseif ($from === false) { + continue; + } elseif ($from === null) { + $dest[$to] = self::get($array, $to); } else { - if ($from === null) $value = null; - else $value = self::pget($array, $from); + $dest[$from] = self::get($array, $to); } - $selected[$to] = $value; } } - return $selected; + return $dest; } /** @@ -334,10 +344,11 @@ class cl { * - [$key => null] --> $dest[$key] = null * - [$pkey] --> $dest[$key] = self::pget($array, $pkey) * avec $key = implode(".", $pkey)) - * - [null] --> NOP + * - [null] --> $dest[] = null + * - [false] --> NOP */ static final function pselect($array, ?array $pkeys): array { - $selected = []; + $dest = []; $index = 0; foreach ($pkeys as $key => $pkey) { if ($key === $index) { @@ -354,9 +365,9 @@ class cl { $value = self::pget($array, $pkey); } } - $selected[$key] = $value; + $dest[$key] = $value; } - return $selected; + return $dest; } /**