JavaScriptの美しさ(多次元配列ソート)
※以前別の場所で書いた文章を備忘的に書き記しておきます。
【投稿年月日】2007-10-24 【ジャンル】PHP/MySQL | JavaScript
PHPでは多次元配列の要素でソートをする場合、例えばusortとcreate_functionを使って以下のように書きます。<?php
$list = array(
array("no"=>3, "cat"=>5, "body"=>"リンゴ"),
array("no"=>2, "cat"=>4, "body"=>"みかん"),
array("no"=>4, "cat"=>5, "body"=>"ナシ"),
array("no"=>6, "cat"=>3, "body"=>"バナナ"),
array("no"=>1, "cat"=>4, "body"=>"オレンジ")
);
usort($list, create_function('$a, $b', 'return $a["cat"]-$b["cat"];'));
print_r("<pre>");
print_r($list);
print_r("</pre>");
?>
$list = array(
array("no"=>3, "cat"=>5, "body"=>"リンゴ"),
array("no"=>2, "cat"=>4, "body"=>"みかん"),
array("no"=>4, "cat"=>5, "body"=>"ナシ"),
array("no"=>6, "cat"=>3, "body"=>"バナナ"),
array("no"=>1, "cat"=>4, "body"=>"オレンジ")
);
usort($list, create_function('$a, $b', 'return $a["cat"]-$b["cat"];'));
print_r("<pre>");
print_r($list);
print_r("</pre>");
?>
多次元配列$listがcatという要素の上り順でソートされましたが、これでは若干不満が残ります。catだけでなく、noでもソートしたかったからです。
複数条件でソートする場合、usortの部分を以下のように書き直します。
usort($list, create_function('$a, $b', 'return ($a["cat"]>$b["cat"]) ? 1 :(($a["cat"]<$b["cat"]) ? -1 : $a["no"]-$b["no"]);'));
これでcatでソートした上で、noでもソートできました。ちなみに、下り順にソートする場合は、$aと$bを入れ替えればOKです。でも、ソート条件が増えると、それだけ分岐も増えるので、コードが冗長になってしまい美しくありません。と言うか、匿名関数のcreate_functionを使う時点で美しくないです(なんとかしてほしい)。
最近使うことの多いJavaScriptはどうかと言うと、以下の通り。
<script language="JavaScript" type="text/javascript"><!--
var list = [
{"no":3, "cat":5, "body":"リンゴ"},
{"no":2, "cat":4, "body":"みかん"},
{"no":4, "cat":5, "body":"ナシ"},
{"no":6, "cat":3, "body":"バナナ"},
{"no":1, "cat":4, "body":"オレンジ"}
];
list.sort(function(a, b) {return a.cat-b.cat});
var text="";
for(var i=0; i<list.length; i++) {
text += "\n no:" + list[i].no + " cat:" + list[i].cat + " body:" + list[i].body;
}
alert(text);
//--></script>
var list = [
{"no":3, "cat":5, "body":"リンゴ"},
{"no":2, "cat":4, "body":"みかん"},
{"no":4, "cat":5, "body":"ナシ"},
{"no":6, "cat":3, "body":"バナナ"},
{"no":1, "cat":4, "body":"オレンジ"}
];
list.sort(function(a, b) {return a.cat-b.cat});
var text="";
for(var i=0; i<list.length; i++) {
text += "\n no:" + list[i].no + " cat:" + list[i].cat + " body:" + list[i].body;
}
alert(text);
//--></script>
多次元配列listをcatの上り順だけでソートしていますが、noを含めた複数条件でソートする場合、list.sortの部分を以下のように書き直します。
list.sort(function(a, b) {return a.cat-b.cat || a.no-b.no});
単に「||」で追加したソート条件を区切るだけ。条件が増えれば、その分「||」で継ぎ足していけばOK。実にシンプルで美しいコードです。PHPでも同様のことができないかと、いろいろとやってみましたが、残念ながらやり方が分かりませんでした。SQLのように複数条件でソートする場面は、そう多くはないのですが、ちょっと悔しかったりします。
EDIUNET | PHP/MySQL | 独り言 | 提供サービス | JavaScript