[PHP-users 18070]Re: 二つのキーを使用してソートしたい。
KOYAMA Tetsuji
koyama @ hoge.org
2003年 9月 25日 (木) 18:27:46 JST
小山です。
At Thu, 25 Sep 2003 15:57:34 +0900,
Yutaka Miura wrote:
> 一つのキーを使用してソートはできたのですが、
> 二つのキーでソートしようと場合
> どのように組んだらよいでしょうか?
> ご教授願いますでしょうか?
> $data[0][0] = 3;
> $data[1][0] = 1;
> $data[2][0] = 2;
> $data[3][0] = 3;
> $data[4][0] = 2;
> $data[5][0] = 1;
> $data[6][0] = 3;
>
> $data[0][1] = 20030925;
> $data[1][1] = 20030925;
> $data[2][1] = 20030925;
> $data[3][1] = 20030924;
> $data[4][1] = 20030925;
> $data[5][1] = 20030925;
> $data[6][1] = 20030924;
>
> function cmp($a, $b) {
> return strcmp($a[1],$b[1]);
> }
>
> usort($data, "cmp");
usort() を使うところまでは良いのですが、なぜその比較関数 cmp() の中
で文字列比較をしているのでしょうか? もしかして 20030925 などの数値は文
字列のつもりなのでしょうか? そうであるなら
$data[0][1] = '20030925';
のようにきちんと文字列であることを明示した方が、ソースも見やすくなりま
すし、思わぬトラブルにも合わなくてすみます。
さてどのようにして2次元の配列をソートするかですが、その前にまず、比
較関数(この場合は cmp()) の引数には何が入るか考えてみましょう。
$data は 2次元配列なので、例えばその一つの要素 $data[0] もまた配列に
なり、array(3, 20030925) という値が入っています。ということは cmp() に
渡される引数も $data[0] と同様の値、つまり配列になります。
> 求めたい結果
> 1 : 20030925
> 1 : 20030925
> 2 : 20030925
> 2 : 20030925
> 3 : 20030925
> 3 : 20030924
> 3 : 20030924
この希望結果から、ソート条件を考えると
1. まず $data[?][] を降順でソートし、
2. 次に $data[][?] を昇順でソートする
ということになります。以上を踏まえて比較関数を書くと
function cmp($a, $b) {
// まず最初の項で比較
$result = $a[0] - $b[0];
// もし同じ値なら
if ($result == 0) {
// 2番目の項で比較。(昇順なので符号を逆にする)
$result = -($a[1] - $b[1]);
}
return $result;
}
のようになります。(2項目めは数値として扱っています)
別に難しいことではないので、上記のように順序だてて考えてみましょう。
--
小山 哲志@ビート・クラフト
koyama @ beatcraft.com
koyama @ hoge.org
PHP-users メーリングリストの案内