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

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

ただいまの
回答率

90.49%

  • PHP

    20792questions

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

  • jQuery

    6915questions

    jQueryは、JavaScriptライブラリのひとつです。 簡単な記述で、JavaScriptコードを実行できるように設計されています。 2006年1月に、ジョン・レシグが発表しました。 jQueryは独特の記述法を用いており、機能のほとんどは「$関数」や「jQueryオブジェクト」のメソッドとして定義されています。

  • Excel

    1592questions

    Excelは、マイクロソフト社が開発しているデータ集計や分析を行う表計算ソフトの一つです。文書作成や表計算、資料作成などの多彩な機能を備えており、統合パッケージであるMicrosoft Officeに含まれています。

  • CSV

    670questions

    CSV(Comma-Separated Values)はコンマで区切られた明白なテキスト値のリストです。もしくは、そのフォーマットでひとつ以上のリストを含むファイルを指します。

検索表をPHPを使って作りたい

解決済

回答 3

投稿

  • 評価
  • クリップ 1
  • VIEW 817

ckaposndbbba

score 199

こんにちは。

CSVを読み込んで、検索表を自動生成したいです。

「検索表」とはどういうものか、と言うと、
1:口元に髭がある・・・・・・2へ
1:口元に髭がない・・・・・・3へ
2:頭部は偏平で幅広い・・・・・・ナマズ
2:頭部は偏平でない・・・・・・ドジョウ
3:体は左右に偏平、中央付近が幅広い・・・・・・フナ
3:体は左右に偏平ではない・・・・・・メダカ
(ー wikipediaより)
というふうに、生物などを見分けられるものです。
たとえば、口元に髭があったら、2番へ行きます。
そこで、頭部が偏平でなかったら、ドジョウだと見分けられるわけです。


こういうものを自動生成したいです。


元となるCSVは、
"ナマズ","口元に髭あり","頭部は偏平"
"ドジョウ","口元に髭あり","頭部は偏平でない"
"フナ","口元に髭なし","体は左右に偏平"
"メダカ","口元に髭なし","体は左右に偏平でない"
といった、それぞれの項目ごとに対応する特徴。

ここから、PHPで、どこが違うかを分析して、上記のような検索表を作りたいです(全く同じものではなくて大丈夫です)。

とりあえず、csvを読み込むのと、違うところを抽出する関数を作ってみましたが。。。

<?php
$data = file_get_contents('data.csv');
$temp = tmpfile();
$csv  = array();
     
fwrite($temp, $data);
rewind($temp);

while (($data = fgetcsv($temp, 0, ",")) !== FALSE) {
    $csv[] = $data;
}
fclose($temp);

/* $csvの中身

Array ( 
  [0] => Array ( 
    [0] => ナマズ 
    [1] => 髭あり 
    [2] => 頭は偏平 
  ) 
  [1] => Array ( 
    [0] => ドジョウ 
    [1] => 髭あり 
    [2] => 頭は偏平でない 

  ...以下略
*/


function is_same($a,$b){
    if(!is_array($a) || !is_array($b)){
        return "";
        die();
    }
    $count_a = count($a);
    $count_b = count($b);
    if($count_a !== $count_b){
        return "";
        die();
    }
    
    
    for($i = 1;$i < $count_a;$i++){
        if($a[$i] !== $b[$i]){
            return $i;
            break;
            die();
        }
    }
}

この先が全く分かりません。また、違うところを抽出する関数も、どこか間違えているかもしれません。

お願いします、困っています!
  • 気になる質問をクリップする

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

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

    クリップを取り消します

  • 良い質問の評価を上げる

    以下のような質問は評価を上げましょう

    • 質問内容が明確
    • 自分も答えを知りたい
    • 質問者以外のユーザにも役立つ

    評価が高い質問は、TOPページの「注目」タブのフィードに表示されやすくなります。

    質問の評価を上げたことを取り消します

  • 評価を下げられる数の上限に達しました

    評価を下げることができません

    • 1日5回まで評価を下げられます
    • 1日に1ユーザに対して2回まで評価を下げられます

    質問の評価を下げる

    teratailでは下記のような質問を「具体的に困っていることがない質問」、「サイトポリシーに違反する質問」と定義し、推奨していません。

    • プログラミングに関係のない質問
    • やってほしいことだけを記載した丸投げの質問
    • 問題・課題が含まれていない質問
    • 意図的に内容が抹消された質問
    • 広告と受け取られるような投稿

    評価が下がると、TOPページの「アクティブ」「注目」タブのフィードに表示されにくくなります。

    質問の評価を下げたことを取り消します

    この機能は開放されていません

    評価を下げる条件を満たしてません

    評価を下げる理由を選択してください

    詳細な説明はこちら

    上記に当てはまらず、質問内容が明確になっていない質問には「情報の追加・修正依頼」機能からコメントをしてください。

    質問の評価を下げる機能の利用条件

    この機能を利用するためには、以下の事項を行う必要があります。

回答 3

checkベストアンサー

0

急ぎで組んだので、結果表示部分がかなり雑ですが、とりあえず動くと思います。

入力データの条件が、「種類が多くて、特徴の項目が多い複雑なもの」ということですが、下のコードでは、とりあえず分岐が必ず2つに分かれるデータを渡しています。
1列目が「結果」、2列目以降が「特徴」で、個数は可変にできると思います。

これを実現するため、再帰処理など、多少複雑なことをしています。
余裕があれば別途で解説も追記したいのですが、いったんこれでよろしくお願いします。

よかったらご自身で改良してみて下さい。
根本的にバグっててどうしようもない、または疑問点等ありましたら、お知らせいただけると幸いです。

<?php

/* 木構造をつくる */
function toTree($answer, $conditions) {
    $condition = array_shift($conditions);
    if ($conditions) {
        return array($condition => toTree($answer, $conditions));
    } else {
        return array($condition => $answer);
    }
}

$csv = array(
    '"結果1","色1","形1","大きさ1","匂い1","価格1"',
    '"結果2","色2","形2","大きさ2","匂い2","価格2"',
    '"結果3","色1","形3","大きさ3","匂い3","価格3"',
    '"結果4","色2","形4","大きさ4","匂い4","価格4"',
    '"結果5","色1","形1","大きさ5","匂い5","価格5"',
    '"結果6","色2","形2","大きさ6","匂い6","価格6"',
    '"結果7","色1","形3","大きさ7","匂い7","価格7"',
    '"結果8","色2","形4","大きさ8","匂い8","価格8"',
    '"結果9","色1","形1","大きさ1","匂い9","価格9"',
    '"結果10","色2","形2","大きさ2","匂い10","価格10"',
    '"結果11","色1","形3","大きさ3","匂い11","価格11"',
    '"結果12","色2","形4","大きさ4","匂い12","価格12"',
    '"結果13","色1","形1","大きさ5","匂い13","価格13"',
    '"結果14","色2","形2","大きさ6","匂い14","価格14"',
    '"結果15","色1","形3","大きさ7","匂い15","価格15"',
    '"結果16","色2","形4","大きさ8","匂い16","価格16"',
    '"結果17","色1","形1","大きさ1","匂い1","価格17"',
    '"結果18","色2","形2","大きさ2","匂い2","価格18"',
    '"結果19","色1","形3","大きさ3","匂い3","価格19"',
    '"結果20","色2","形4","大きさ4","匂い4","価格20"',
    '"結果21","色1","形1","大きさ5","匂い5","価格21"',
    '"結果22","色2","形2","大きさ6","匂い6","価格22"',
    '"結果23","色1","形3","大きさ7","匂い7","価格23"',
    '"結果24","色2","形4","大きさ8","匂い8","価格24"',
    '"結果25","色1","形1","大きさ1","匂い9","価格25"',
    '"結果26","色2","形2","大きさ2","匂い10","価格26"',
    '"結果27","色1","形3","大きさ3","匂い11","価格27"',
    '"結果28","色2","形4","大きさ4","匂い12","価格28"',
    '"結果29","色1","形1","大きさ5","匂い13","価格29"',
    '"結果30","色2","形2","大きさ6","匂い14","価格30"',
    '"結果31","色1","形3","大きさ7","匂い15","価格31"',
    '"結果32","色2","形4","大きさ8","匂い16","価格32"',
        );

$identificationKey = array();
foreach ($csv as $line) {
    $columns = explode(',', $line);
    list($answer, $conditions) = array(array_shift($columns), $columns);

    $identificationKey = array_merge_recursive($identificationKey, toTree($answer, $conditions));
}


/* 木構造から結果を表示する */
function getResults($conditions, &$bookings, $number) {
    $results = array();
    if ($number < 10) {
        $number = "0{$number}";
    }
    foreach ($conditions as $condition => $next) {
        if (is_array($next)) {
            $nextNumber = array_shift($bookings);
            $results[] = "{$number}:{$condition}・・・・・・{$nextNumber}へ";
            $results = array_merge($results, getResults($next, $bookings, $nextNumber));
        } else {
            $results[] = "{$number}:{$condition}・・・・・・{$next}";
        }
    }
    asort($results);
    return $results;
}

$bookings = range(2, 9999);
foreach (getResults($identificationKey, $bookings, 1) as $result) {
    echo "{$result}\n";
}

投稿

  • 回答の評価を上げる

    以下のような回答は評価を上げましょう

    • 正しい回答
    • わかりやすい回答
    • ためになる回答

    評価が高い回答ほどページの上位に表示されます。

  • 回答の評価を下げる

    下記のような回答は推奨されていません。

    • 間違っている回答
    • 質問の回答になっていない投稿
    • スパムや攻撃的な表現を用いた投稿

    評価を下げる際はその理由を明確に伝え、適切な回答に修正してもらいましょう。

  • 2015/03/04 11:50

    おおおおおおおおおおおおおお!!!!!ありがとうございます!!!
    できました〜!
    これを参考にしながら、作っていきたいと思います。
    勉強になります。。。
    ありがとうございましたm(_ _)m

    キャンセル

  • 2015/04/06 20:43

    こんにちは.度々のコメント失礼します.
    実は,バグが1つあって,自分の力で直そうとして試行錯誤したのですが,できませんでした(>_<)
    実は,検索が進んでいくと,必要のない項目まですべて出し切っちゃうんですよね.
    たとえば,以下の様な出力があるのですが,
    1. 赤である...4へ
    2. 青である..8へ
    3. 緑である...15へ
    4. つぶつぶがある...5
    5. 甘い匂いがする...6
    6. 緑のへたがついている...7
    7. 若いものは緑色である...いちご
    ・・・・・・
    なんですが,この場合,4〜7は必要ないですよね.
    4番で,「いちご」と断定してしまったほうが早いですよね.
    説明が分かりにくいかもしれませんが,
    改善できませんか?
    ぼくもいろいろ試して見たのですが,うまくできませんでした.

    よろしくおねがいします.

    キャンセル

0

CSVは3列で、

"答え","条件1","条件2"

の形式という前提で、このような方法はどうでしょうか。

<?php

//コードを見た感じ、{$csv}にはこんなデータが入っていそうなので、これを使って実装します。
$csv = array(
    '"ナマズ","口元に髭あり","頭部は偏平"',
    '"ドジョウ","口元に髭あり","頭部は偏平でない"',
    '"フナ","口元に髭なし","体は左右に偏平"',
    '"メダカ","口元に髭なし","体は左右に偏平でない"',
    );

/* 
 * 多重連想配列で、検索表の木構造を表現します。
 * 今回の入力に対して、
 * [
 * '"口元に髭あり"' => ['"頭部は偏平"' => '"ナマズ"', '"頭部は偏平でない"' => '"ドジョウ"'],
 * '"口元に髭なし"' => ['"体は左右に偏平"' => , '"フナ"', '"体は左右に偏平でない"' => '"メダカ"']
 * ]
 * が構築されるはずです。
 */
$identificationKey = array();

foreach ($csv as $line) {
    list($answer, $condition1, $condition2) = explode(',', $line);//"答え","条件1","条件2"に分解

    if (isset($identificationKey[$condition1])) {
        $identificationKey[$condition1][$condition2] = $answer;
    } else {
        $identificationKey[$condition1] = array($condition2 => $answer);
    }
}

// 構築した木構造から、検索表の各文言を表示します。
$results = array();

$conditionNumber = 1;
foreach ($identificationKey as $condition1 => $answers) {
    $conditionNumber++;
    $results[] = "1:{$condition1}・・・{$conditionNumber}へ";
    foreach ($answers as $condition2 => $answer) {
        $results[] = "${conditionNumber}:{$condition2}・・・{$answer}";
    }
}
asort($results);//並び替え

foreach ($results as $result) {
    echo "{$result}\n";
}

投稿

  • 回答の評価を上げる

    以下のような回答は評価を上げましょう

    • 正しい回答
    • わかりやすい回答
    • ためになる回答

    評価が高い回答ほどページの上位に表示されます。

  • 回答の評価を下げる

    下記のような回答は推奨されていません。

    • 間違っている回答
    • 質問の回答になっていない投稿
    • スパムや攻撃的な表現を用いた投稿

    評価を下げる際はその理由を明確に伝え、適切な回答に修正してもらいましょう。

  • 2015/03/03 12:49

    詳しく教えていただき、ありがとうございます!
    早速、そのコードで試してみました。
    すると、きれい〜に表示されました!

    しかし。。。
    たとえば、
    "結果","特徴1","特徴2","特徴3","特徴4","特徴5"
    "結果2","特徴1","特徴2","特徴3","特徴4","特徴5"
    "結果3","特徴1","特徴2","特徴3","特徴4","特徴5"
    "結果4","特徴1","特徴2","特徴3","特徴4","特徴5"
    "結果5","特徴1","特徴2","特徴3","特徴4","特徴5"
    "結果6","特徴1","特徴2","特徴3","特徴4","特徴5"
    みたいな、種類が多くて、特徴の項目が多い複雑なものでは、うまくいきません。
    コードを見て、直そうとしてみましたが、なおさら変になりました。。。。

    複雑なcsvでも、読み取りたいです。。。
    素人ですみません、

    可能でしょうか。。?

    よろしくお願いしますm(_ _)m

    キャンセル

0

仕事の依頼なら下記のようなサイトを使うと良いと思いますよ

クラウドワークス
ランサーズ

投稿

  • 回答の評価を上げる

    以下のような回答は評価を上げましょう

    • 正しい回答
    • わかりやすい回答
    • ためになる回答

    評価が高い回答ほどページの上位に表示されます。

  • 回答の評価を下げる

    下記のような回答は推奨されていません。

    • 間違っている回答
    • 質問の回答になっていない投稿
    • スパムや攻撃的な表現を用いた投稿

    評価を下げる際はその理由を明確に伝え、適切な回答に修正してもらいましょう。

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

  • ただいまの回答率 90.49%
  • 質問をまとめることで、思考を整理して素早く解決
  • テンプレート機能で、簡単に質問をまとめられる

関連した質問

同じタグがついた質問を見る

  • PHP

    20792questions

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

  • jQuery

    6915questions

    jQueryは、JavaScriptライブラリのひとつです。 簡単な記述で、JavaScriptコードを実行できるように設計されています。 2006年1月に、ジョン・レシグが発表しました。 jQueryは独特の記述法を用いており、機能のほとんどは「$関数」や「jQueryオブジェクト」のメソッドとして定義されています。

  • Excel

    1592questions

    Excelは、マイクロソフト社が開発しているデータ集計や分析を行う表計算ソフトの一つです。文書作成や表計算、資料作成などの多彩な機能を備えており、統合パッケージであるMicrosoft Officeに含まれています。

  • CSV

    670questions

    CSV(Comma-Separated Values)はコンマで区切られた明白なテキスト値のリストです。もしくは、そのフォーマットでひとつ以上のリストを含むファイルを指します。