Webリクエストのパラメタを指定したパラメタ名の順でソートするプログラムを書いてみました。
プログラム自体は汎用的なので、パラメタのソートに限らず、それ以外でも利用可能です。
<?php class ParameterSorter { private $sortOrder; // パラメタのソート順を指定 public function __construct($sortOrder) { $this->sortOrder = array_flip($sortOrder); $this->max = count($sortOrder); } // uksortを使って指定されたパラメタ順でソート // $sortOrderのキーをパラメタ名に変換して、uksortを使うのは性能を上げるためです。 // ソート順が指定されていないパラメタは、ソート順が指定されたパラメタの後になるように実装しています。 public function sort(&$parameters) { uksort($parameters, function($a, $b){ return ($this->sortOrder[$a] ?? $this->max) - ($this->sortOrder[$b] ?? $this->max); }); } // PHPのuksortは安定でない(同順位の場合もとの順序が保存されない)らしいので、元の順序を確実に保証するバージョンも作成しました。 public function stableSort(&$parameters) { $originalOrder = array_flip(array_keys($parameters)); uksort($parameters, function($a, $b) use($originalOrder){ $compared = ($this->sortOrder[$a] ?? $this->max) - ($this->sortOrder[$b] ?? $this->max); if($compared === 0) { return $originalOrder[$a] - $originalOrder[$b]; } return $compared; }); } }
下記は使用例になります。
<?php $sortOrder = ['A', 'B', 'C', 'D', 'E']; $sorter = new Util\ParameterSorter($sortOrder); $parameters = [ 'Z' => 'z', 'F' => 'f', 'C' => 'c', 'K' => 'k', 'A' => 'a', 'B' => 'b', ]; $sorter->sort($parameters); print_r($parameters); $parameters = [ 'Z' => 'z', 'F' => 'f', 'C' => 'c', 'K' => 'k', 'A' => 'a', 'B' => 'b', ]; $sorter->stableSort($parameters); print_r($parameters); // 下記のような出力結果が得られます。 // サンプルで使ったパラメタ配列では、単純なuksortバージョンと安定バージョンで差は出ませんでした。 // Array //( // [A] => a // [B] => b // [C] => c // [Z] => z // [F] => f // [K] => k //) //Array //( // [A] => a // [B] => b // [C] => c // [Z] => z // [F] => f // [K] => k //)
コメント