人力検索はてな
モバイル版を表示しています。PC版はこちら
i-mobile

PHPの質問です
こちらの質問の続きです
http://q.hatena.ne.jp/1465834502
a.csvがあります
a.csv
==============
みかん,A,1,
みかん,B,4
みかん,C,3,
メロン,A,1,
メロン,B,2,
メロン,C,2,
==============
これを一番目に2列目を優先し 2番目に一列目を優先してソートし
その結果をb.csvに出力したいです
その場合どのようなPHPを組めばいいでしょうか?
よろしくお願いします

●質問者: gaugjiuaej
●カテゴリ:ウェブ制作
○ 状態 :終了
└ 回答数 : 1/1件

▽最新の回答へ

1 ● tobeoscontinue
ベストアンサー
<?php
function str_putcsv($csv, $c=',', $t="\n") {
 return implode($c, $csv).$t;
}

$csv = array_map('str_getcsv', file('a.csv'));

usort($csv, function ($a, $b) {
 if ($a[1] == $b[1])
 return $a[0] == $b[0] ? 0 : ($a[0] < $b[0] ? -1 : 1);
 else return $a[1] < $b[1] ? -1 : 1; 
});

file_put_contents('b.csv', array_map('str_putcsv', $csv));

>一番目に2列目を優先し 2番目に一列目を優先してソート
http://q.hatena.ne.jp/1465834502にあるcallback関数の部分を書き換えます。
$a[1] == $b[1]の2列目が等しい場合のみ一列目の$a[0] == $b[0]を調べます。

また1列目、2列目は文字列なのでstrcmpを使ったほうがコードはすっきりします。
ただ数値が二桁以上だと正しく比較できません。

usort($csv, function ($a, $b) {
$c = strcmp($a[1], $b[1]);
return $c == 0 ? strcmp($a[0], $b[0]) : $c;
}

csv配列を文字列化するためにstr_putcsvとしました。
array_map('str_putcsv', $csv)の返値は配列なのですがfile_put_contentsが
全ての要素を出力してくれます。


gaugjiuaejさんのコメント
3列目が二桁以上の整数の場合はどこを書き換えたらいいでしょうか?

tobeoscontinueさんのコメント
3列目がソートの対象でなければ二桁以上の整数であっても問題ではありません。 if文を使ったusortの方であれば3列目がソートの対象であっても問題がありません。 例えば一番目に2列目を優先し 2番目に三列目を優先してソートなら if ($a[1] == $b[1]) return $a[2] == $b[2] ? 0 : ($a[2] < $b[2] ? -1 : 1); else return $a[1] < $b[1] ? -1 : 1; と添字を変えるだけです。 strcmpを使ったusortでは $c = strcmp($a[1], $b[1]); return $c == 0 ? strcmp($a[2], $b[2]) : $c; は成立しないということです。
関連質問

●質問をもっと探す●



0.人力検索はてなトップ
8.このページを友達に紹介
9.このページの先頭へ
対応機種一覧
お問い合わせ
ヘルプ/お知らせ
ログイン
無料ユーザー登録
はてなトップ