• ベストアンサー

絞り込んでランダム表示

PHPでランダムに文章を表示するようにしたいのですが、以下のような場合はどのようにしたらよいでしょうか? ちなみにSQLを使わずにしようと思っています 1 A text1 2 A × 3 B text2 4 B text3 5 A text4 まず、このようなデータがあるとして、「A」という条件で絞込みます 1 A text1 2 A × 5 A text4 次に絞り込んだ中から「×(未記入)」のモノを除きます 1 A text1 5 A text4 最終的にここからランダムでどちらか1件のみを表示するようにします という流れを作りたいのですが、最後の絞り込んだ条件からランダムに表示する方法が思いつかず悩んでおります どのようにすれば、出来ますでしょうか?

質問者が選んだベストアンサー

  • ベストアンサー
  • yambejp
  • ベストアンサー率51% (3827/7415)
回答No.5

つまり以下のような仕様でよいのですね? ・$linesという文字列の変数がある。 ・1行に3つの要素をもち、行の区切りは改行(\n)である。 ・3つめの要素はない(未記入)場合がある。 ・2番目の要素で絞りこみをする、ただし3番目の要素がない場合は 対象外とする。 ・結果をランダムに1件のみ文字列で抽出する。 前のコードを元にざっと書いてみました。 <?PHP $lines=<<<eof 100 A text100 5 A text1 4 A 3 B text2 2 B text3 1 A text4 eof; //要素の区切りはタブ function choiceData($data,$jouken){ if(!is_array($data)) return false; foreach($data as $key=>$val){ if($val['条件']!=$jouken OR $val['データ']=="") unset($data[$key]); } $rand_keys = array_rand($data, 1); foreach($data as $key=>$val){ if($key!=$rand_keys) unset($data[$key]); } $key=key($data); $str="{$key}\t{$data[$key]['条件']}\t{$data[$key]['データ']}"; return $str; } $line=explode("\n",$lines); foreach($line as $val){ list($no,$bunrui,$item_name) = explode("\t", $val); $data[$no]=Array('条件'=>$bunrui,'データ'=>$item_name); } $str=choiceData($data,'A'); print $str; ?> まず行を得るのは行の区切り文字でexplodeします。 その場合の$lineは配列になります。 それをforeachで回せば1行ごとの処理ができます。 ここでは$dataという配列に整理しなおして、命題の処理をしています。

ex5000
質問者

お礼

ありがとうございました おかげさまで、思い通りのソースが出来ました 今まで自分が使用していた関数の組み合わせが、限られたものでした おかげさまで視野が広がりました

その他の回答 (4)

  • yambejp
  • ベストアンサー率51% (3827/7415)
回答No.4

#3です。 >100行以上になった場合でも記述していく必要があるのでしょうか? 勘違いしないでくださいね。 回答の際にもかきましたが「データをどのように持つかによる」 はなしなので、質問者さんがどうやってデータを持つか書いてくれないから こういった書き方をしただけで、別の方法でもつならその方法に 最適な書き方ができると思います。 とにかく正確な回答がほしいのなら、もうすこし仕様をきちんと 提示してもらえると助かります

ex5000
質問者

補足

詳しく内容を書いておいたほうがよかったです すみませんでした 具体的に何がしたいかというと、ゲームのアイテム情報をランダムに1件表示できるようにしたいのです 100 A text100 ・ ・ 5 A text1 4 A × 3 B text2 2 B text3 1 A text4 (説明時は自分なりにわかりやすく上から1と書きましたが、上に行を増やしていきます) AやBの部分は武器や防具の分類で、text1やtext2の部分はアイテム名と性能みたいな感じで、×は調査中のため保留というような状態です それを1つのテキストデータにまとめておいて、武器(Aの部分)ならtext1やtext4をランダムに1つ表示する、防具(Bの部分)もtext2やtext3をランダムに1つ表示するといったような具合にしたいのです データの数がかなりの量になりそうなので、うまく使い分けしたいと思っていました 絞り込んだデータから1件だけランダムに表示する方法がわからず、質問した次第です 条件の絞込みを foreach($lines as $line) { $line = rtrim($line); list($no,$bunrui,$item_name) = explode("\t", $line);{ if($bunrui == weapon) といった具合に絞込みをしていたのですが、foreachでしてしまうとデータ数繰り返されてしまいますが、他の絞込み方法が思いつかず、1件のみランダムに表示するところに辿りつけておりません そもそもforeachを使っての絞込みがまずいとも思っています #1の方の方法では、絞込みから配列の格納とあったのですが、それも分からずです これで分かっていただけますでしょうか? 説明が下手ですみませんがよろしくお願いします

  • yambejp
  • ベストアンサー率51% (3827/7415)
回答No.3

データをどのように持つかによりますね・・・ 配列を使うならarray_randなどが楽かもしれません。 以下サンプルです。 <?PHP function choiceData($data,$jouken){ if(!is_array($data)) return false; foreach($data as $key=>$val){ if($val['条件']!=$jouken OR $val['データ']=="") unset($data[$key]); } $rand_keys = array_rand($data, 1); foreach($data as $key=>$val){ if($key!=$rand_keys) unset($data[$key]); } return $data; } $data=Array( 1=>Array('条件'=>'A','データ'=>'text1') ,2=>Array('条件'=>'A','データ'=>'') ,3=>Array('条件'=>'B','データ'=>'text2') ,4=>Array('条件'=>'B','データ'=>'text3') ,5=>Array('条件'=>'A','データ'=>'text4') ); $data=choiceData($data,'A'); print_r($data); ?>

参考URL:
http://www.php.net/manual/ja/function.array-rand.php
ex5000
質問者

補足

ユーザー定義関数はイマイチ苦手で使用しておりませんでしたが、なんとなく分かりました ただ、 $data=Array( 1=>Array('条件'=>'A','データ'=>'text1') ,2=>Array('条件'・・・ の部分で100行以上になった場合でも記述していく必要があるのでしょうか?

  • hkd9001
  • ベストアンサー率48% (99/204)
回答No.2

#1 です。ごめんなさい、1か所訂正です。 上記(3)最後の部分 誤.....「 0 から N の整数を得る」 正.....「 0 から N-1 の整数を得る」 でした。「0 から N」では、1個余計ですものね。失礼しました~!

  • hkd9001
  • ベストアンサー率48% (99/204)
回答No.1

おはようございます。 この場合は、 (1) 最後に絞り込んだデータ(ここでは text1 と text4 ですね)を配列に格納する。 (2) この配列の要素数を調べる(これ用の関数があります)。得られた個数を N としましょう。ご質問の例では N = 2 になりますね。 (3) 乱数を発生させる(これ用の関数があります)。一般に得られる数値は 0 から 1 の間の値なので、これに N を掛けてから小数以下を切り捨てて(これ用の関数があります)、 0 から N の整数を得る。 (4) これを使って(1)の配列を参照すればよい。 でよろしいのではないかしら?

ex5000
質問者

補足

ありがとうございます ただ、更に迷宮入りしそうです・・・ (1)の方法がわからないのです (2)からは $arr = $array[mt_rand(0,count($array)-1)]; $row = explode("\t", $arr); で出来そうなのですが アプローチが間違っているのか、悩み中です(T_T

関連するQ&A