1

クエリとファイル読み取りを組み合わせた長いプロセスから生成された3つの文字列があり、それぞれが相互に関連しています。


例:

$versions = "1 2 5 4 10 6 8 7 3 9";
$weights = "50.2 60.5 35 10 15.98 60 50 60.1 70 75";
$ids = "512 318 112 326 155 191 977 961 943 441";

バージョン番号の昇順で並べ替えたいと思います。

結果の例:

$versions = "1 2 3 4 5 6 7 8 9 10";
$weights = "50.2 60.5 70 10 35 60 60.1 50 75 15.98";
$ids = "512 318 943 326 112 191 961 977 441 155";

私の質問は、これを現在行っているよりも効率的な方法はありますか?
これらの文字列は大きくなる可能性があることに注意してください。これまでに見た中で最大のものは、最大600の異なるバージョンです。

私は次のことをします:

  • 文字列を爆発させる
  • バージョン番号をキーとして配列をコピーする
  • キーで配列を並べ替える
  • 文字列を元に戻す

これがコードと実際の例です:

$versions = "1 2 5 4 10 6 8 7 3 9";
$weights = "50.2 60.5 35 10 15.98 60 50 60.1 70 75";
$ids = "512 318 112 326 155 191 977 961 943 441";

$a_versions = explode(" ", $versions);
$a_weights = explode(" ", $weights);
$a_ids = explode(" ", $ids);

$s_versions = array();
$s_weights = array();
$s_ids = array();

//set keys to correspond to version number
foreach($a_versions as $key => $ver){
    $s_versions[$ver] = $a_versions[$key];
    $s_weights[$ver] = $a_weights[$key];
    $s_ids[$ver] = $a_ids[$key];
}

//sort according to keys
ksort($s_versions, SORT_NUMERIC);
ksort($s_weights, SORT_NUMERIC);
ksort($s_ids, SORT_NUMERIC);

//implode back
$versions = implode(" ", $s_versions); 
$weights = implode(" ", $s_weights); 
$ids = implode(" ", $s_ids); 

echo "
    <pre>
        $versions
        $weights
        $ids
    </pre>
";

/*==========
Results
    1 2 3 4 5 6 7 8 9 10
    50.2 60.5 70 10 35 60 60.1 50 75 15.98
    512 318 943 326 112 191 961 977 441 155
==========*/

パフォーマンスの向上#1:

foreachループをarray_combineに置き換えると、パフォーマンスが少し向上する可能性があります。– svens

確かに、単純な単体テストによると、約11〜15%高速です。

4

2 に答える 2

1

これは私が見つけることができる最高のものです:

$versions = array_flip(explode(' ', $versions));
$weights = explode(' ', $weights);
$ids = explode(' ', $ids);

ksort($versions, SORT_NUMERIC);
foreach ($versions as $version => $idx) {
  $result[0][] = $version;
  $result[1][] = $weights[$idx];
  $result[2][] = $ids[$idx];
}

return array(
  implode(' ', $result[0]),
  implode(' ', $result[1]),
  implode(' ', $result[2]),
);

私がテストしたもの(最初のコードとarray_combineを使用したコードを含む)の比較については、http://codepad.viper-7.com/flcvnOを参照し てください。

于 2012-05-22T11:36:25.023 に答える
1

これが別のアプローチです。これは、キーがない最も単純な例です。

$versions = "1 2 5 4 10 6 8 7 3 9";
$weights = "50.2 60.5 35 10 15.98 60 50 60.1 70 75";
$ids = "512 318 112 326 155 191 977 961 943 441";

$a_versions = explode(" ", $versions);
$a_weights = explode(" ", $weights);
$a_ids =  explode(" ", $ids);

$version_weight_id = array_map(null, $a_versions, $a_weights, $a_ids);

print_r($version_weight_id);

よりキーのあるものが必要な場合は、次のようなマップ関数が必要になります。

function version_weight_id($v, $w, $id) {

    return array('version' => $v, 'weight' => $w, 'id' => $id);

}

$versions = "1 2 5 4 10 6 8 7 3 9";
$weights = "50.2 60.5 35 10 15.98 60 50 60.1 70 75";
$ids = "512 318 112 326 155 191 977 961 943 441";

$a_versions = explode(" ", $versions);
$a_weights = explode(" ", $weights);
$a_ids =  explode(" ", $ids);

$version_weight_id = array_map('version_weight_id', $a_versions, $a_weights, $a_ids);

array_multisort($version_weight_id, $a_versions);

print_r($version_weight_id);

編集:

マップ関数を必要としない別のアプローチは次のとおりです。

$versions = "1 2 5 4 10 6 8 7 3 9";
$weights = "50.2 60.5 35 10 15.98 60 50 60.1 70 75";
$ids = "512 318 112 326 155 191 977 961 943 441";

$a_versions = explode(" ", $versions);
$a_weights = explode(" ", $weights);
$a_ids =  explode(" ", $ids);

$weights_ids = array_map(null, $a_weights, $a_ids);
$versions_weights_ids = array_combine($a_versions, $weights_ids);

print_r($versions_weights_ids);

キャッチは、主キーがバージョンであり、サブアレイ0キーが重みであり、サブアレイ1キーがIDであることを知っている必要があるということです。

結果を印刷するには、次を使用します。

foreach($versions_weights_ids as $version => $weight_id) {
echo "
    <pre>
        $version
        {$weight_id[0]}
        {$weight_id[1]}
    </pre> ";
}

ajaxソリューションをお探しの場合は、JSONを検討し、次のようなものを使用します。

$versions = "1 2 5 4 10 6 8 7 3 9";
$weights = "50.2 60.5 35 10 15.98 60 50 60.1 70 75";
$ids = "512 318 112 326 155 191 977 961 943 441";

$a_versions = explode(" ", $versions);
$a_weights = explode(" ", $weights);
$a_ids =  explode(" ", $ids);

$weights_ids = array_map(null, $a_weights, $a_ids);
$versions_weights_ids = array_combine($a_versions, $weights_ids);

echo json_encode($versions_weights_ids);

このようにして、フレームワークの各メソッドを使用するか、特定のバージョン(または複数のバージョン)をターゲットにして出力することができます。

于 2012-05-22T12:46:31.400 に答える