2

それで、

問題

カスタム配列の並べ替えに問題があります。私は配列を持っています:

$rgData = [
  3 => 1,
  5 => 0,
  1 => 2,
  9 => 0,
  0 => 1,
  4 => 2,
  2 => 1,
  7 => 0,
  6 => 0,
  8 => 0,
];

- カウント付きのキーが含まれています (実際には、 を使用したいくつかの操作の後に来ましたarray_count_values)。今、私はそれを並べ替えたい:

  • 低い値が最初に来る (つまり、 で実行できる通常の昇順ソートasort())
  • 1 つの値内で、キーを昇順に並べ替える必要があります (ここで助けが必要です)

上記のサンプルの場合、結果は次のようになります。

[5=>0、6=>0、7=>0、8=>0、9=>0、0=>1、2=>1、3=>1、1=>2、4=>2 ]

私のアプローチ

ユーザー定義による並べ替えでこれを解決する方法がわかりません。比較するための値のみを受け入れるusortか、キーのみを受け入れ、比較関数で両方が必要です。私が今持っている唯一の方法は、これを行うことです:uasortuksort

$rgData = ['3'=>1, '5'=>0, '1'=>2, '9'=>0, '0'=>1, '4'=>2, '2'=>1, '7'=>0, '6'=>0, '8'=>0];
$rgTemp = [];
asort($rgData);
$i     = 0;
$mPrev = current($rgData);
foreach($rgData as $mKey=>$mValue)
{
        $rgTemp[$mPrev==$mValue?$i:++$i][$mKey] = $mValue;
        $mPrev = $mValue;
}
$rgTemp = array_map(function($rgX)
{
        ksort($rgX);
        return $rgX;
}, $rgTemp);
$rgData = [];
//can't use call_user_func_array('array_merge', $rgTemp) - it spoils numeric keys
foreach($rgTemp as $rgX)
{
        foreach($rgX as $mKey=>$mValue)
        {
                $rgData[$mKey] = $mValue;
        }
}
//var_dump($rgData);

-つまり、最初に配列を値で分割してから、作業を行います。

質問

これをより簡単な方法で行うにはどうすればよいですか?ファイナル ギャザリング ループでasort+ サイクルksortを使用しました。array_map一時配列も使用されます。奇妙に見えます。より簡単な方法が存在することを願っています。

4

1 に答える 1

2

これはあなたが望むことをするはずです。キーでソートしますが、関数内の値にアクセスできるため、それをソート基準としても使用できます。

uksort($rgData, function($a, $b) use($rgData){
    $aVal = $rgData[$a];
    $bVal = $rgData[$b];

    // Compare the values
    if($aVal === $bVal){
        // If they are the same, compare the keys
        return $a - $b;
    }
    // Otherwise compare the values
    return $aVal - $bVal;
});
于 2013-09-20T18:27:49.967 に答える