1

従業員が計算したデータのPHP配列(DBから取得)があります。従業員1人あたり約10列あり、そのうち8列は数値です(他の2列はIDと名前です)。ここに短いサンプルがあります:

デビッド:1024、75、22  
マイク:500、100、25  
ジェフ:700、82、10  

任意の(数値)フィールドで配列を簡単に並べ替えて、誰が上/下にいるかを表示できますが、ファイナルテーブルビューに表示したいのは値によるランク付けなので、ユーザーはそうする必要はありません。テーブルを並べ替えて再並べ替えて、必要なものを取得します。これは、最初の列でソートされたテーブルの例であり、括弧内にランキングを示しています。

デビッド:1024(#1)、75(#3)、22(#2)  
ジェフ:700(#2)、82(#2)、10(#3)  
マイク:500(#3)、100(#1)、25(#1)  

これで、最も簡単なアプローチは、テーブルを列で並べ替え、行インデックスをランキングとして使用し、列ごとに繰り返すことです。もっと効率的な方法を見つけられるかどうか疑問に思いました。

順序付けられたキュー(ランク付けが必要な列ごとに1つ)を使用し、配列を1回スキャンして、値をキューにプッシュすることを考えました。だが:

  1. PHPには、配列以外のデータ構造はありません(外部追加を使用しない限り)
  2. 私はこれがより効率的であるとは確信していません。

誰かが最善のアプローチを提案したり、アレイを数回再ソートする必要があることを確認したりできますか?

御時間ありがとうございます!

4

2 に答える 2

1

よく検討した結果、「列ごとに並べ替える」ルートを選択することにしました。興味のある人が後で参照できるように、クラスに追加した関数を次に示します。ランク付けする必要のある列ごとに1回呼び出されます。

   private function calculateRankings(&$employees, $columnName) {
        $comparer = "return (\$a[$columnName][0] == \$b[$columnName][0]) ? 0 :  (\$a[$columnName][0] > \$b[$columnName][0] ? -1 : 1);";
        usort($employees, create_function('$a,$b', $comparer));
        foreach($employees as $key => &$employee) {
            $employee[$columnName][1] = $key + 1;
        }
    }

+1は、キーがゼロベースであるためです。

この関数の準備として、ランク付けする必要のある各フィールドを2要素配列に変換します。最初の([0])には値が含まれ、2番目の([1])には最後にランクが含まれます。
すなわち:$employees['salary'] = array(1550, 0);。次に、次のように関数を呼び出します
$this->calculateRankings($employees, 'salary');

いつか、これが誰かに役立つことを心から願っています。すべてのレスポンダー/コメンターに感謝します!

更新4/9:以前に提供した関数が機能しませんでした-3番目のパラメーター(この場合は列名)を比較関数に渡す方法はありません。それを行う唯一の方法は、静的クラス変数を使用するか、最終的に作成したcreate_functionハックを使用することです。ご迷惑をおかけして申し訳ありません。

于 2012-04-05T02:41:00.933 に答える
0

私はあなたが最初のアプローチに固執しなければならないのではないかと心配しています。

すべての列を反復処理して、個々の列のランキング情報を計算する必要があります。

あなたができることは、そのタスクをより効率的に達成するためにアルゴリズムを最適化することです。

PS:パフォーマンスは常に重要ですが、アルゴリズムは、複雑さ、成長の順序、または実行時間について心配するほど珍しいものではないと思います。

于 2012-04-04T17:09:34.410 に答える