PHP Sorting Arrays(配列のソート)
■配列の値によるソート(0から始まる数値インデックスに直す)
以下のように、sort関数を使うと値をアルファベット順にソートし、インデックスを振りなおす。また第二引数にはSORT_REGULAR、SORT_NUMERIC、SORT_STRINGなどを取り、型を変換する事もできる。
<?php $tmpAry = array( 'person1' => 'Emily', 'person2' => 'Dennis', 'person3' => 'Andy' ); sort($tmpAry); var_dump($tmpAry); /* array(3) { [0]=> string(4) "Andy" [1]=> string(6) "Dennis" [2]=> string(5) "Emily" } */ ?>
逆順にソートするには
以下のようにrsort関数を使用すると、sort関数を使った時とは逆順に並ぶ。
<?php $tmpAry = array( 'person1' => 'Andy', 'person2' => 'Dennis', 'person3' => 'Emily' ); rsort($tmpAry); var_dump($tmpAry); /* array(3) { [0]=> string(5) "Emily" [1]=> string(6) "Dennis" [2]=> string(4) "Andy" } */ ?>
戻り値について
以下の例のようにsort関数は配列自身を変換し、戻り値は処理の成否についてのbool値が格納されるだけである。基本的に配列ソート関数は全て配列自身を変換し、戻り値は処理の成否としてのbool値となる。
<?php var_dump(sort($tmpAry));//true or false ?>
ユーザー指定関数での並び替え
以下のようにusort関数を使用する。第二引数には文字列で関数名を指定する。(但し、以下の例はグローバル空間が汚れないように、create_function関数を使っての匿名関数を利用している。)
<?php $ary = array(1, 5, 2); usort( $ary, create_function( '$a,$b', 'if($a < $b){return 1;}if($a === $b){return 0;}if($a > $b){return -1;}' ) ); var_dump($ary); /* array(3) { [0]=> int(5) [1]=> int(2) [2]=> int(1) } */ ?>
■配列の値によるソート(キーとの関係は維持)
以下のようにasort関数を使うとキーとの関係は維持されつつ、値によるソートが行われる。
<?php $tmpAry = array( 'person1' => 'Emily', 'person2' => 'Dennis', 'person3' => 'Andy' ); asort($tmpAry); var_dump($tmpAry); /* array(3) { ["person3"]=> string(4) "Andy" ["person2"]=> string(6) "Dennis" ["person1"]=> string(5) "Emily" } */ ?>
逆順にしたい時にはarsort関数を使用し、ユーザー定義関数でソートしたいときにはuasort関数を使用する。但し、今考える限りではキーとの関係を維持したままソートする有用なシチュエーションは思い浮かばない。
■配列のキーによるソート
以下のようにksort関数を使うと、配列のキーによってソートされる。
<?php $tmpAry = array( 'Naomi' => 'student', 'Dennis' => 'driver', 'Emily' => 'traveler' ); ksort($tmpAry); var_dump($tmpAry); /* array(3) { ["Dennis"]=> string(6) "driver" ["Emily"]=> string(8) "traveler" ["Naomi"]=> string(7) "student" } */ ?>
また、逆順にしたい時はkrsort関数を使い、ユーザー定義関数でソートしたい時はuksort関数を使う。
PHPは内部的に配列のキーとは別に順序を持っている。内部順序とキーの順序が違う場合、json_encode関数を使うと変換が異なるので注意しなくてはならない。
<?php $tmpAry = array( 2 => 'Naomi', 1 => 'Dennis', 0 => 'Emily' ); var_dump($tmpAry); ksort($tmpAry); var_dump($tmpAry); /* array(3) { [2]=> string(5) "Naomi" [1]=> string(6) "Dennis" [0]=> string(5) "Emily" } string(38) "{"2":"Naomi","1":"Dennis","0":"Emily"}" array(3) { [0]=> string(5) "Emily" [1]=> string(6) "Dennis" [2]=> string(5) "Naomi" } string(26) "["Emily","Dennis","Naomi"]" */ ?>
■まとめ
一覧にまとめると以下のようになる。
処理 | 昇順 | 降順 | ユーザー定義 |
---|---|---|---|
値によるソート、インデックスの再ラベリング | sort | rsort | usort |
値によるソート | asort | arsort | uasort |
キーによるソート | ksort | krsort | uksort |
個人的な考えだが「昇順と降順」は引数でコントロールできるようにしてもイイと思う。
ユーザー定義関数について
<?php $ary = array(1, 5, 2); usort( $ary, create_function( '$a,$b', 'if($a < $b){return 1;}if($a === $b){return 0;}if($a > $b){return -1;}' ) ); var_dump($ary); /* array(3) { [0]=> int(5) [1]=> int(2) [2]=> int(1) } */ ?>
- 引数を2つとる
- 「if($a < $b){return 1;}」は「$a<$b」の時、そのままの順序である事を意味する。
- 「if($a > $b){return -1;}」は「$a>$b」の時、前後を入れ替える事を意味する。
- 「if($a === $b){return 0;}」は「$a === $b」の時、特に何もしない事を意味する。
つまり、比較関数は最初の引数が2番目の引数より小さいか、等しいか、大きい場合に、 それぞれゼロ未満、ゼロに等しい、ゼロより大きい整数を返す。
■自然順ソート
通常のソート関数を使うと、以下のように不自然な結果となる。
<?php $tmpAry = array('10km', '5km', '7km'); sort($tmpAry); var_dump($tmpAry); /* array(3) { [0]=> string(4) "10km" [1]=> string(3) "5km" [2]=> string(3) "7km" } */ ?>
以下のようにnatsort関数を使用すると、数字+単位のように扱われ、自然な並び順となる。また、大文字と小文字を区別しないnatcasesort関数もある。
<?php $tmpAry = array('10km', '5km', '7km'); natsort($tmpAry); var_dump($tmpAry); /* array(3) { [1]=> string(3) "5km" [2]=> string(3) "7km" [0]=> string(4) "10km" } */ ?>
各関数について
- bool natsort(array &$ary)
- 自然順で配列をソートする。
- bool natcasesort(array &$ary)
- 大文字と小文字を区別しない自然順アルゴリズムでソートする。
■配列のシャッフル
以下のようにshuffle関数を使うと、配列をランダムに並び替えることができる。以下の結果は実行ごとに異なるが、キーは必ず削除され数値のインデックスが割り当てられる。
<?php $tmpAry = array( 'person1' => 'Emily', 'person2' => 'Dennis', 'person3' => 'Andy' ); shuffle($tmpAry); /* array(3) { [0]=> string(6) "Dennis" [1]=> string(5) "Emily" [2]=> string(4) "Andy" } */ ?>
各巻数について
- bool shuffle(array &$ary)
- 配列をシャッフルする。但し、既存のキーは削除される。
TrackBack URL :
Comments (0)
コメントはまだありません»
No comments yet.
RSS feed for comments on this post.TrackBack URL
Leave a comment