CSVの出力で困っています。
CSV1のファイルに
ABC列で次のようなデータがあるとして
A列 B列 C列
太郎,30才,大阪
次郎,35才,東京
三郎,40才,長野
CSV2のファイルには
ABC列で次のようなデータがあるとします。
A列 B列 C列
太郎,果物,A型
太郎,果物,A型
太郎,果物,A型
太郎,果物,A型
太郎,果物,A型
太郎,果物,A型
次郎,焼肉,B型
次郎,焼肉,B型
次郎,焼肉,B型
次郎,焼肉,B型
次郎,焼肉,B型
三郎,中華,C型
三郎,中華,C型
三郎,中華,C型
三郎,中華,C型
三郎,中華,C型
三郎,中華,C型
CSV1のファイルのA列の値を検索キーワードに
CSV2のファイルのA列を検索します。
検索でヒットした同じ値同士をまとめ
CSVとして下記のような感じで出力する方法をご教授いただけますでしょうか。
A列
太郎太郎太郎太郎太郎太郎
次郎次郎次郎次郎次郎
三郎三郎三郎三郎三郎三郎
phpで実現したいと考えています。
よろしくお願いします。
function array_column(array $input, $columnKey, $indexKey = null) { // <= 5.5.0
$ary = array();
foreach ($input as $r)
$ary[] = $r["$columnKey"];
return $ary;
}
function array_column_combine($inputs, $col) {
$ary = array();
foreach ($inputs as $r) {
$k = $r["$col"];
$ary["$k"][] = $r;
}
return $ary;
}
$csv1 = array_map("str_getcsv", file("csv1"));
if (0) {
$pat = '/^'.implode('.*$|^', array_column($csv1, 0)).'.*$/m';
$s = preg_match_all($pat, file_get_contents("csv2"), $csv2m);
$csv2 = array_map("str_getcsv", $csv2m[0]);
}
else $csv2 = array_map("str_getcsv", file("csv2"));
$m = array_column_combine($csv2, 0);
foreach (array_column($csv1, 0) as $n) {
foreach ($m["$n"] as $c2) echo $c2["0"];
echo "\n";
}
/*
PHPでCSVを扱う場合fgetcsvを使うのでしょうがコードが長いので今回はfileとstr_getcsvを使いました。
file("csv1")で行単位の一次元の配列になります。その行をstr_getcsvで更に配列に区切ることでarray_map
の結果は二次元の配列になります。
array_column($csv1, 0)は$CSV1の0列目、つまり名前(A列)だけを取り出し配列にして返します。
phpのversionが5.5.0からは実装されているのでそうであればfunction array_columnの部分は必要ありません。
array_column_combine($csv2, 0)も似ていますが名前で連想配列にしています。
こうすることで「同じ値同士をまとめる」ことが出来ます。
var_dump($m)してみてもいいでしょう。
後は順に名前を表示するだけです。
preg_match_allを使ってcsv2から条件に合うものだけを抽出するという方法もあります。
今回の例では全てにマッチするので意味がないですが抽出が一部だけの場合は意味があるでしょう。
パターンを作り出すためにarray_column($csv1, 0)で名前だけを取り出したものをimplodeします。
$pat = '/^'.implode('.*$|^', array_column($csv1, 0)).'.*$/m';
$pat の内容は下記になります。
"/^太郎.*$|^次郎.*$|^三郎.*$/m"
これを使ってpreg_match_allでcsv2の全体の中からマッチする行だけが取り出せます。
$s = preg_match_all($pat, file_get_contents("csv2"), $csv2m);
$csv2m[0]にマッチした行がはいっているので
$csv2 = array_map("str_getcsv", $csv2m[0]);
で二次元の配列に変換しています。
*/
?>