質問をすることでしか得られない、回答やアドバイスがある。

15分調べてもわからないことは、質問しよう!

新規登録して質問してみよう
ただいま回答率
85.48%
PHP

PHPは、Webサイト構築に特化して開発されたプログラミング言語です。大きな特徴のひとつは、HTMLに直接プログラムを埋め込むことができるという点です。PHPを用いることで、HTMLを動的コンテンツとして出力できます。HTMLがそのままブラウザに表示されるのに対し、PHPプログラムはサーバ側で実行された結果がブラウザに表示されるため、PHPスクリプトは「サーバサイドスクリプト」と呼ばれています。

Q&A

解決済

2回答

4763閲覧

PHP 二種類のCSVのマッチングについて

smiley-_-smiley

総合スコア26

PHP

PHPは、Webサイト構築に特化して開発されたプログラミング言語です。大きな特徴のひとつは、HTMLに直接プログラムを埋め込むことができるという点です。PHPを用いることで、HTMLを動的コンテンツとして出力できます。HTMLがそのままブラウザに表示されるのに対し、PHPプログラムはサーバ側で実行された結果がブラウザに表示されるため、PHPスクリプトは「サーバサイドスクリプト」と呼ばれています。

0グッド

1クリップ

投稿2016/01/24 02:04

編集2016/01/25 03:18

※丸投げが過ぎるとのご指摘をいただきましたため、質問内容を大幅に編集しております。大変失礼いたしました。

手元にはメンバーリストと所属一覧という二種類のCSVがあります。
メンバーリスト上の所属はツリー構造をしており、同じ名称の所属名が複数使用されています。

メンバーリストの『所属1』~『所属3』に対応するIDを所属一覧のCSVから検索して、出食したいと思います。

id, 名前, 所属1, 所属2, 所属3

id, 名前, 所属1_id, 所属1, 所属2_id, 所属2, 所属3_id, 所属3

単純にメンバーリスト上の所属Nと所属一覧上の所属名を比較するだけだと
所属2や3において
1-1>傘係>傘まとめ担当は90
1-2>傘係>傘まとめ担当は190
1-3>傘係>傘まとめ担当は310
をそれぞれ返してほしいのに、最初にヒットした90が返ってしまうと考えました。

そこで所属一覧を読み込んだ後にメンバーリスト上の所属1~所属3との比較用として、以下のデータを作成して、一致するIDを取り出そうとしました。

(1)所属1との比較用データ:'1-1' -> 10
(2)所属1+所属2との比較用データ:'1-1|傘係' -> 40
(3)所属1+所属2+所属3との比較用データ:'1-1|傘係|傘まとめ担当' -> 90

しかし、比較用のデータを作成しようとしました段階でどのようにすればいいのかわからず、手詰まりになってしまいました。
今回は所属1~所属3の三階層ですが、今後階層が増えることも考えられるため、再帰的にIDと親IDが一致する所属名を一番下の階層から文字列を結合すればいいのかとも思いましたが、単純にループした場合は(1)(2)(3)をそれぞれ作ることができませんでした。

どなたか比較データの作成方法、もしくは考え方についてご教示いただけないでしょうか。

php

1<?php 2$user_filepath ="user.csv"; //ユーザー一覧 3$section_filepath = "section.csv"; //所属一覧 4$output_file = "output.csv"; 5 6$user_list = array(); 7$section_list = array(); 8$output = array(); 9 10//ユーザー一覧を読み込む 11$user_file = new SplFileObject($user_filepath); 12$user_file->setFlags(SplFileObject::READ_CSV); 13$n=0; //先頭行を飛ばすためのカウンタ 14foreach ($user_file as $line){ 15 if($n>0){ 16 $user_list[] =array( 17 'id' => $line[0], 18 'name' => $line[1], 19 'section1' => $line[2], 20 'section2' => $line[3], 21 'section3' => $line[4], 22 ); 23 } 24 $n++; 25} 26 27//所属一覧を読み込む 28$section_file = new SplFileObject($section_filepath); 29$section_file->setFlags(SplFileObject::READ_CSV); 30$i=0; //先頭行を飛ばすためのカウンタ 31foreach ($section_file as $line){ 32 if($i>0){ 33 $section_list[] = array( 34 'id' => $line[0], 35 'section_name' => $line[1], 36 'parent_id' => $line[2] 37 ); 38 } 39} 40 41 42print_r($user_list); 43//print_r($section_list);
●メンバー一覧(user.csv) id,名前,所属1,所属2,所属3 1,山田太郎,1-1,傘係,傘まとめ担当 2,田中一郎,1-1,ごみ係,ゴミ捨て担当 3,杉田玄白,1-2,傘係,傘立て掃除担当 4,高杉晋作,1-3,生き物係, 5,坂本龍馬,1-1,体育係,
●所属一覧(section.csv) id,カテゴリー,親ID 10,1-1,0 20,1-2,0 30,1-3,0 40,傘係,10 50,ごみ係,10 60,生き物係,10 140,体育係,10 150,傘係,20 160,ごみ係,20 170,生き物係,20 180,体育係,20 270,傘係,30 280,ごみ係,30 290,生き物係,30 300,体育係,30 90,傘まとめ担当,40 100,傘立て掃除担当,40 70,ゴミ捨て担当,50 80,ゴミ袋交換担当,50 110,エサやり担当,60 120,水替え担当,60 130,水槽掃除担当,60 190,傘まとめ担当,150 200,傘立て掃除担当,150 210,ゴミ捨て担当,160 220,ゴミ袋交換担当,160 230,エサやり担当,170 240,水替え担当,170 250,水槽掃除担当,170 310,傘まとめ担当,270 320,傘立て掃除担当,270 330,ゴミ捨て担当,280 340,ゴミ袋交換担当,280 350,エサやり担当,290 360,水替え担当,290 370,水槽掃除担当,290

メンバーリストには各自の所属が記載されていますが、人によって所属1のみであったり、所属1~所属3が埋まっています。

所属は、同じ名称でも親が異なる場合は別IDが与えられています。
例)ID_所属名
10_1-1┬40_傘係┬90_傘まとめ担当
│ └100_傘立て掃除担当
└50_ごみ係┬70_ゴミ捨て担当
│ └80_ゴミ袋交換担当
└60_生き物係┬110_エサやり担当
│ └120_水替え担当
│ └130_水槽掃除担当
└140_体育係

20_1-2┬150_傘係┬190_傘まとめ担当
│ └200_傘立て掃除担当
└160_ごみ係┬210_ゴミ捨て担当
│ └220_ゴミ袋交換担当
└170_生き物係┬230_エサやり担当
│ └240_水替え担当
│ └250_水槽掃除担当
└180_体育係

30_1-3┬270_傘係┬310_傘まとめ担当
│ └320_傘立て掃除担当
└280_ごみ係┬330_ゴミ捨て担当
│ └340_ゴミ袋交換担当
└290_生き物係┬350_エサやり担当
│ └360_水替え担当
│ └370_水槽掃除担当
└300_体育係

気になる質問をクリップする

クリップした質問は、後からいつでもMYページで確認できます。

またクリップした質問に回答があった際、通知やメールを受け取ることができます。

バッドをするには、ログインかつ

こちらの条件を満たす必要があります。

tanat

2016/01/25 00:06

こちらの質問が他のユーザから「やってほしいことだけを記載した丸投げの質問」という指摘を受けました 「質問を編集する」ボタンから編集を行い、調査したこと・試したことを記入していただくと、回答が得られやすくなります。
tanat

2016/01/25 07:36 編集

今回のケースに限らず、配列を再帰的に走査するコードを書くことは出来る状態ですか?
smiley-_-smiley

2016/01/26 04:56

再起処理は概要は理解しているつもりではありますが、正しく理解できてはいないと思います。出先のため、作業できる環境になったら、試してみたコードを追記させていただきます。
guest

回答2

0

以下のチェックを所属1~所属3の各データで行い、対象のIDを取得することができました。

1.所属名が一致する
2.ユーザーデータ中の親IDが一つ上の階層のIDと一致する

PHP

1<?php 2ini_set('display_errors', 1); 3$user_filepath ="user.csv"; //ユーザー一覧 4$section_filepath = "section.csv"; //所属一覧 5$output_file = "output.csv"; 6 7 8$user_list = array(); 9$section_list = array(); 10$output = array(); 11 12 13//ユーザー一覧を読み込む 14$user_file = new SplFileObject($user_filepath); 15$user_file->setFlags(SplFileObject::READ_CSV); 16$n=0; //先頭行を飛ばすためのカウンタ 17foreach ($user_file as $line){ 18 if($n>0 && $line[0]!='' && $line[1]!='' && $line[2]!='' && $line[3]!=''){ 19 $user_list[] =array( 20 'id' => $line[0], 21 'name' => $line[1], 22 'section1' => $line[2], 23 'section2' => $line[3], 24 'section3' => $line[4], 25 ); 26 } 27 $n++; 28} 29 30//所属一覧を読み込む 31$section_file = new SplFileObject($section_filepath); 32$section_file->setFlags(SplFileObject::READ_CSV); 33$i=0; //先頭行を飛ばすためのカウンタ 34foreach ($section_file as $line){ 35 if($i>0 && $line[0]!='' && $line[1]!='' && $line[2]!=''){ 36 $section_list[] = array( 37 'id' => $line[0], 38 'section_name' => $line[1], 39 'parent_id' => $line[2] 40 ); 41 } 42 $i++; 43 44} 45 46 47foreach($user_list as $user_data){ 48 //ユーザーデータの所属に対応するIDを取得 49 $ret = sectionCheck($user_data, $section_list); 50 51 //返り値をユーザーデータに結合する 52 $user_data+= $ret; 53 $output[] = $user_data; 54} 55 56print_r($output); 57 58 59 60/************************************** 61 所属データのIDを返す 62*************************************/ 63function sectionCheck($user, $section){ 64 $ret = array( 65 'section1_id' => '', 66 'section2_id' => '', 67 'section3_id' => '' 68 ); 69 foreach($section as $s){ 70 if($user['section1'] == $s['section_name']){ 71 //デバッグ用に所属データを出力 72 //echo $s['id'].":".$s['section_name'].PHP_EOL; 73 $p_id_1 = $s['id']; 74 $ret['section1_id'] = $s['id']; 75 } 76 } 77 foreach($section as $s){ 78 if($user['section2'] == $s['section_name'] && $p_id_1 == $s['parent_id']){ 79 //デバッグ用に所属データを出力 80 //echo $s['id'].":".$s['section_name'].":".$s['parent_id'].PHP_EOL; 81 $p_id_2 = $s['id']; 82 $ret['section2_id'] = $s['id']; 83 } 84 } 85 foreach($section as $s){ 86 if($user['section3'] == $s['section_name'] && $p_id_2 == $s['parent_id']){ 87 //デバッグ用に所属データを出力 88 //echo $s['id'].":".$s['section_name'].":".$s['parent_id'].PHP_EOL; 89 $ret['section3_id'] = $s['id']; 90 } 91 } 92 return $ret; 93}

●出力結果

PHP

1Array 2( 3 [0] => Array 4 ( 5 [id] => 1 6 [name] => 山田太郎 7 [section1] => 1-1 8 [section2] => 傘係 9 [section3] => 傘まとめ担当 10 [section1_id] => 10 11 [section2_id] => 40 12 [section3_id] => 90 13 ) 14 15 [1] => Array 16 ( 17 [id] => 2 18 [name] => 田中一郎 19 [section1] => 1-1 20 [section2] => ごみ係 21 [section3] => ゴミ捨て担当 22 [section1_id] => 10 23 [section2_id] => 50 24 [section3_id] => 70 25 ) 26 27 [2] => Array 28 ( 29 [id] => 3 30 [name] => 杉田玄白 31 [section1] => 1-2 32 [section2] => 傘係 33 [section3] => 傘立て掃除担当 34 [section1_id] => 20 35 [section2_id] => 150 36 [section3_id] => 200 37 ) 38 39 [3] => Array 40 ( 41 [id] => 4 42 [name] => 高杉晋作 43 [section1] => 1-3 44 [section2] => 生き物係 45 [section3] => 46 [section1_id] => 30 47 [section2_id] => 290 48 [section3_id] => 49 ) 50 51 [4] => Array 52 ( 53 [id] => 5 54 [name] => 坂本龍馬 55 [section1] => 1-1 56 [section2] => 体育係 57 [section3] => 58 [section1_id] => 10 59 [section2_id] => 140 60 [section3_id] => 61 ) 62)

投稿2016/01/26 08:32

smiley-_-smiley

総合スコア26

バッドをするには、ログインかつ

こちらの条件を満たす必要があります。

test_hf

2016/01/26 14:00

おお。良かったですね!
guest

0

ベストアンサー

csvデータを取得は出来ているものとして記載します。
まずメンバー一覧のデータをforeachで回します。


$fileにメンバー一覧が入っている。
$listに所属一覧が入っている。

$new_list = array();
foreach ($file as $line) {
$records['id'] = $line[0]; //id
$records['name'] = $line[1]; //名前

//所属一覧で回してメンバー一覧の所属1とカテゴリーを照らし合わせる foreach($list as $list_line){ if($line[2] == $list_line[1]){ $records['section1_id'] = $list_line[0]; //所属1_id break; } } $records['section1'] = $line[2]; //所属1 $records['section2_id'] = ''; //所属2_id(無い場合があるので先に空をいれておく) $records['section2'] = ''; //所属2(無い場合があるので先に空をいれておく) //所属一覧で回してメンバー一覧の所属2とカテゴリーを照らし合わせる if(strlen($line[3]) > 0){//メンバー一覧の所属2に値がある場合 foreach($list as $list_line){ if($line[3] == $list_line[1]){ $records['section2_id'] = $list_line[0]; //所属2_id break; } } } $records['section2'] = $line[3]; //所属2 $records['section3_id'] = ''; //所属3_id(無い場合があるので先に空をいれておく) $records['section3'] = ''; //所属3(無い場合があるので先に空をいれておく) //所属一覧で回してメンバー一覧の所属3とカテゴリーを照らし合わせる if(strlen($line[4]) > 0){//メンバー一覧の所属3に値がある場合 foreach($list as $list_line){ if($line[4] == $list_line[1]){ $records['section3_id'] = $list_line[0]; //所属3_id break; } } $records['section3'] = $line[4]; //所属3 } array_push($new_list,$records);

}

$new_listに入った配列をcsvなどに吐き出してやれば要望のリストができると思います。

所属は、同じ名称でも親が異なる場合は別IDが与えられています。

これがなにをふるのかわからないので、上記処理では属性一覧のidをふるようにしています。

それから動作確認は全くしていないので、あくまで参考ということで。
メンバーのループの中で、該当の所属に対して所属一覧で回して該当カテゴリーと紐付ける考えです。

投稿2016/01/24 08:56

test_hf

総合スコア80

バッドをするには、ログインかつ

こちらの条件を満たす必要があります。

smiley-_-smiley

2016/01/25 03:23

回答ありがとうございます。質問の言葉が足りておらず申し訳ありません。 質問を訂正させていただきました。 ご提示いただいた方法は、所属1~所属3の文字列を比較して、一致したものを取り出しているかと思います。 その場合、所属一覧に『傘係』が複数存在するため、正しいIDを取り出すことができないのです。
test_hf

2016/01/25 13:33 編集

> 再帰的にIDと親IDが一致する所属名 親IDは何と紐付いているのですか? > 所属一覧に『傘係』が複数存在するため カテゴリの重複がある場合何をみて該当のIDと紐付けるのですか?
smiley-_-smiley

2016/01/26 00:57

>親IDは何と紐付いているのですか? 親IDを指定して別のカテゴリーのIDを指定します。 『1-1>傘係』の場合、CSVを読み込んだ配列では以下のようになります。 $section_list[0] = array('id'=>'10', 'section_name'=>'1-1', 'parent_id'=>'0'); //最上位の場合は親IDは0 $section_list[1] = array('id'=>'40', 'section_name'=>'傘係', 'parent_id'=>'10'); //親IDとして1-1のIDである10を指定している >カテゴリの重複がある場合何をみて該当のIDと紐付けるのですか? 同一名称のカテゴリーは自身のIDは別々となり、別の親IDを指定することで区別します。 『1-2>傘係』の場合 $section_list[3] = array('id'=>'20', 'section_name'=>'1-1', 'parent_id'=>'0'); //最上位の場合は親IDは0 $section_list[4] = array('id'=>'100', 'section_name'=>'傘係', 'parent_id'=>'20'); //親IDとして2-2のIDである20を指定している
guest

あなたの回答

tips

太字

斜体

打ち消し線

見出し

引用テキストの挿入

コードの挿入

リンクの挿入

リストの挿入

番号リストの挿入

表の挿入

水平線の挿入

プレビュー

15分調べてもわからないことは
teratailで質問しよう!

ただいまの回答率
85.48%

質問をまとめることで
思考を整理して素早く解決

テンプレート機能で
簡単に質問をまとめる

質問する

関連した質問