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)
コメントはまだありません»
コメントはまだありません。
この投稿へのコメントの RSS フィード。TrackBack URL
コメントする