多次元配列の中のキーでソート
$lists = array( array( 'id' => 1, 'name' => 'a', ), array( 'id' => 2, 'name' => 'b', ), array( 'id' => 3, 'name' => 'c', ), array( 'id' => 4, 'name' => 'd', ), );
多次元配列で、idをキーに降順でソート
usort($lists, create_function('$a,$b','return($b[\'id\'] - $a[\'id\']);'));
多次元配列で、nameをキーに昇順でソート
usort($lists, create_function('$a,$b','return($a[\'name\'] - $b[\'name\']);'));
usort()を使えばユーザ定義比較関数を使うことができるので、階層の深い多次元配列でもソート可能。
array_multisort()を使う
array_multisort() は本当に便利な関数で、上記と同じことをができる。
$keys = array(); foreach ($lists as $val) $keys[] = $val['name']; array_multisort($keys, SORT_DESC, $lists);
usort() と array_multisort() の実行速度を比較
apacheのabでパフォーマンスを比較したところ、僕の環境下では array_multisort() の方が、usort() よりも5倍早かった。
連想インデックスを保持しつつソート
$lists = array( 'a' => array( 'id' => 1, 'name' => 'a', ), 'b' => array( 'id' => 2, 'name' => 'b', ), 'c' => array( 'id' => 3, 'name' => 'c', ), 'd' => array( 'id' => 4, 'name' => 'd', ), );
連想配列で、idをキーに降順でソート(連想インデックスを保持)
uasort($lists, create_function('$a,$b','return($b[\'id\'] - $a[\'id\']);'));
連想インデックスでソート
$lists = array( 'safari' => array( 'id' => 1, ), 'ie' => array( 'id' => 2, ), 'firefox' => array( 'id' => 3, ), 'chrome' => array( 'id' => 4, ), 'opera' => array( 'id' => 5, ), );
(多次元)配列で、連想インデックスを降順でソート(連想インデックスを保持)
krsort($lists); //ksort()が昇順
下記の uksort() を使えば、この場合は krsort() と同じ結果に。
uksort($lists, create_function('$a,$b','return(strcasecmp($b,$a));'));
uksort() を使うメリットとしては、やはりユーザ定義比較関数が使えるので、PHPマニュアルにあるように下記のようなことができる。
function cmp($a, $b){ $a = preg_replace('@^(a|an|the) @', '', $a); $b = preg_replace('@^(a|an|the) @', '', $b); return strcasecmp($a, $b); } $a = array("John" => 1, "the Earth" => 2, "an apple" => 3, "a banana" => 4); uksort($a, "cmp");
日付・時刻でソート
$lists = array( array( 'id' => 1, 'date' => '2011-01-01 12:00:00', ), array( 'id' => 2, 'date' => '2010-12-01 12:00:00', ), array( 'id' => 3, 'date' => '2011-02-01 12:00:00', ), array( 'id' => 4, 'date' => '2009-01-01 12:00:00', ), );
strtotime() でタイムスタンプに変換して比較することもできる。便利。
usort($lists, create_function('$a,$b','return(strtotime($a[\'date\']) > strtotime($b[\'date\']));'));