CSVデータを連想配列にして任意の項目の数値で並び替える方法

投稿者: | 2014年4月10日

テキストファイルでデータを保存する方法は、データの件数が少ない場合やデータベースの使えないサーバーを利用している場合には簡単で便利なのだが、通常は読み込んだファイルに保存されている順に表示となる。

チャットや掲示板のデータのように時系列で並ぶものであれば、データの追加時にデータの先頭に追加していくようにしておくだけで支障は無いが、扱うデータによっては、表示させる順番を変更したい場合もあるだろう。

例えば、配列に含まれている更新日時やサイズといった項目のデータを基にソートするケース。

以下のような外部ファイルに記録されているCSVデータがあるとする。

4, pdf, ちゃいろ, 3, 734286, 14/04/10-16:34
3, pdf, ぴんく, 1, 919002, 14/04/10-16:34
2, pdf, あか, 2, 842134, 14/04/10-15:12

新しいデータはデータの先頭に追加するようになっているため、2、3、4の順で追加され、最新データが1件目となるもの。
ニュース記事やブログ等では一般的な表示順とも言える。

上記データを配列として読み込み、表示させたもの。

print_r($lines);

Array
(
	[0] => 4, pdf, ちゃいろ, 3, 734286, 14/04/10-16:34
	[1] => 3, pdf, ぴんく, 1, 919002, 14/04/10-16:34
	[2] => 2, pdf, あか, 2, 842134, 14/04/10-15:12
)

この3件のデータのそれぞれを、さらにCSVで分割して配列にし、連想配列にする

#連想配列にする
for($i=0;$i!=count($lines);$i++){
	$lines2[$i] = explode(', ', $lines[$i]);
}

上記スクリプトで処理したものを表示させたもの。

print_r($lines2);

Array
(
	[0] => Array
		(
			[0] => 4
			[1] => pdf
			[2] => ちゃいろ
			[3] => 3
			[4] => 734286
			[5] => 14/04/10-16:34
		)
	[1] => Array
		(
			[0] => 3
			[1] => pdf
			[2] => ぴんく
			[3] => 1
			[4] => 919002
			[5] => 14/04/10-16:34
		)
	[2] => Array
		(
			[0] => 2
			[1] => pdf
			[2] => あか
			[3] => 2
			[4] => 842134
			[5] => 14/04/10-15:12
		)
)

ぞれぞれの行をキーとして、CSVで分割されているのがわかるだろう。

このデータの中の、4番目の項目の数字順で並び替えをする。

#表示順でソート
foreach ($lines2 as $key => $value){
	$key_id[$key] = $value[3];
}
array_multisort($key_id, SORT_ASC, $lines2);

array_multisortを使い連想配列を一気にソートする。
4番目の項目をキーにソートした配列を表示させたもの。

print_r($lines2);

Array
(
	[0] => Array
		(
			[0] => 3
			[1] => pdf
			[2] => ぴんく
			[3] => 1
			[4] => 919002
			[5] => 14/04/10-16:34
		)
	[1] => Array
		(
			[0] => 2
			[1] => pdf
			[2] => あか
			[3] => 2
			[4] => 842134
			[5] => 14/04/10-15:12
		)
	[2] => Array
		(
			[0] => 4
			[1] => pdf
			[2] => ちゃいろ
			[3] => 3
			[4] => 734286
			[5] => 14/04/10-16:34
		)
)

[3]が数字順になっているのが分かるだろう。

通常は並び替えたこのデータをそのまま表示用に使えば良いが、既存のロジックに挿入する形でこの機能を追加した場合は、並び替えたデータを再びCSVのデータに戻す必要がある。

連想配列になったデータを再びCSVに戻すのは以下

#再度CSVに
$j = 0;
foreach ($lines2 as $value){
	$lines[$j] = implode(", ", $value);
	$j++;
}

表示させたもの。

print_r($lines);

Array
(
	[0] => 3, pdf, ぴんく, 2, 919002, 14/04/10-16:34
	[1] => 2, pdf, あか, 3, 842134, 14/04/10-15:12
	[2] => 4, pdf, ちゃいろ, 1, 734286, 14/04/10-16:34
)

このようにすれば、データがテキストベースであっても、自由な項目を基準にソートすることができる。

 連想配列のソート

$lines
ソートしたい配列データ

#連想配列にする
for($i=0;$i!=count($lines);$i++){
	$lines2[$i] = explode(', ', $lines[$i]);
}

#表示順でソート
foreach ($lines2 as $key => $value){
	$key_id[$key] = $value[3];
}
array_multisort($key_id, SORT_ASC, $lines2);

#旧配列データは消去
$lines = array();

#再度配列に
$j = 0;
foreach ($lines2 as $value){
	$lines[$j] = implode(", ", $value);
	$j++;
}