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を組めばいいでしょうか?
よろしくお願いします

回答の条件
  • 1人5回まで
  • 13歳以上
  • 登録:2016/06/17 16:44:54
  • 終了:2016/06/18 17:11:47

ベストアンサー

id:tobeoscontinue No.1

tobeoscontinue回答回数206ベストアンサー獲得回数482016/06/18 14:42:41

<?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が
全ての要素を出力してくれます。

id:gaugjiuaej

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

2016/06/18 14:47:20
id: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;
は成立しないということです。

2016/06/18 16:01:48

コメントはまだありません

この質問への反応(ブックマークコメント)

「あの人に答えてほしい」「この質問はあの人が答えられそう」というときに、回答リクエストを送ってみてましょう。

これ以上回答リクエストを送信することはできません。制限について

絞り込み :
はてなココの「ともだち」を表示します。
回答リクエストを送信したユーザーはいません