• ベストアンサー

配列の並びかえごにFor文使用

いつもお世話になっております。 今回、配列の要素数に応じて順番を並び替へ、要素数の多いのから少ないものへのforループに挑戦することにしたのですがルーチンが思い浮かばず投稿させていただきました。 DBから 条件1で検索し、その条件でヒットしたid列の値を$hairetu1に格納しております。 条件2で検索し、その条件でヒットしたid列の値を$hairetu2に格納しております。 条件3で検索し、その条件でヒットしたid列の値を$hairetu3に格納しております。 条件4で検索し、その条件でヒットしたid列の値を$hairetu4に格納しております。 条件5で検索し、その条件でヒットしたid列の値を$hairetu5に格納しております。 最大5つの条件で検索できるようにしております。($hairetu変数は全て配列変数として使用しております) 条件1で検索した再に、$hairetu1には、1,2,4という値(id値)が入っており、 条件2で検索した再には、$hairetu2に、1,4という値が入っています。 条件3で検索した再には、$hairetu3に、1,2,3,4という値が入っています。 条件4で検索した再には、$hairetu4に、9999という値が入っています。 条件3で検索した再には、$hairetu5に、1,2という値が入っています。 ※各条件で検索した際に、ヒットしたid数が0の場合、nullが入らないように初期化の時点で9999をセットしております。$hairetu=array(9999); 今回、[条件1 and 条件2 and 条件3 and 条件4 and 条件5] の結果、1と2を最終的に$result_hairetuに格納したいのです。 考えた方法は、 For(i){ for(j){ for(k){ for(l){for(m){ if(hairetu[i]==hairetu[j] && hairetu[i]==hairetu[k]・・・,hairetu[l] ==hairetu[m]){array_push($result_hairetu,hairetu[i])}}}}}} ※i・・・ (i=0;i<count(hairetu1);i++) という方法で、5つのfor文でループし、ifで比較し同じであればresult_hairetuに格納するという手法をとろうとしたのですが、条件2で検索した結果が、1,2の二つであるため、二つ目のfor文を二回走ったところで抜けてしまい処理が途中で終わってしまいます。 途中で抜けるのを防ぐために以下のように配列を並び替えて、 For分で使用するという流れを作りたいのです。 また、今回、hairetu2と5の要素数が同じなのときはどのようにセットしたらよいかもわかりません。要素数が同じである場合はどちらが先でもかまいません。 for(hairetu4){for(hairetu2){for(hairetu5){for(hairetu1){for(hairetu3)}}}} このループの作り方がわかる方がいらっしゃいましたらご教授のほうお願いできないでしょうか?よろしくお願いします。

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

  • ベストアンサー
回答No.2

基本的にforの入れ子にする必要性があまり無いような気がします。 for(i=0;i<hairetu3要素数;i++){  for(j=0;j<hairetu1要素数;j++){   for(k=0;k<hairetu2要素数;k++){    for(l=0;l<hairetu4要素数;l++){     for(m=0;m<hairetu5要素数;m++){      if(hairetu3[i]==hairetu1[j] && hairetu3[i]==hairetu2[j] && hairetu3[i]==hairetu4[j] && hairetu3[i]==hairetu5[j]){ array_push(result_hairetu,hairetu3[i]); }     }    }   }  } } この処理は、つまり 「全ての条件に該当した場合のみIDを返す」 という状態になっていると思います。 これはSQLで WHERE word = '条件1' AND word = '条件2' AND word = '条件3' AND word = '条件4' AND word = '条件5' とやっていることと同じだと思います。 仮にforの入れ子が5個あり、各要素に100個の検索結果が入った場合、繰り返し処理数は100の5乗に近いものとなり、間違いなく無駄な負荷になります。 行いたいことは実現できると思いますが、他の方法を考えることをお勧めします。

ShiftTail
質問者

お礼

なるほど。ありがとうございます。 ちょっと別の方法を考えて見ます。

すると、全ての回答が全文表示されます。

その他の回答 (1)

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

要素数の少ない順にforをつくる意義がわからないです。 どのような効果を期待して要素数順にするかがポイントでしょう。 不可能ではないとは思いますが、やる意味がないのであれば やらずに済ませるに越したことはありません。

ShiftTail
質問者

補足

2点間違っておりました。 ●条件4で検索した結果には、$hairetu4に、9999だけではなく、1も入っております。(1,9999が、はいっています。) ●今回、[条件1 and 条件2 and 条件3 and 条件4 and 条件5] ここの記述が間違っており、 →[各条件で絞り込んだ時の最大のヒット数配列(今回ならヒット数4のhairetu3) and 二番目のヒット数配列(hairetu1) and 3番目のヒット数配列(hairetu2) and 4番目のヒット数配列(hairetu4) and 5番目のヒット数配列(hairetu5)]で共通をidを探し、 なければ、 [各条件で絞り込んだ時の最大のヒット数配列(今回ならヒット数4のhairetu3) and 二番目のヒット数配列(hairetu1) and 3番目のヒット数配列(hairetu2) and 4番目のヒット数配列(hairetu4)] というように 後ろの一つのhairetuを削り4つで共通idを探す。これでもなければ、3つ、2つ、2つの検索結果で共通idがないときは、各条件で絞り込んだ時の最大のヒット数配列(今回ならヒット数4のhairetu3) を result_hairetuに格納し、その内容を表示させるということをしたいのです。よって、コレをさせるためには、要素数の多いものから小さいmのへのループを作る必要があると思ったのです。 <要素の多いものから少ないものへのループにしたい> for(i=0;i<hairetu3要素数;i++){  for(j=0;j<hairetu1要素数;j++){   for(k=0;k<hairetu2要素数;k++){    for(l=0;l<hairetu4要素数;l++){     for(m=0;m<hairetu5要素数;m++){      if(hairetu3[i]==hairetu1[j] && hairetu3[i]==hairetu2[j] && hairetu3[i]==hairetu4[j] && hairetu3[i]==hairetu5[j]){ array_push(result_hairetu,hairetu3[i]); }     }    }   }  } } ただ、この各hairetuの配列変数に入るidの個数はきまっておらず、0個のときもあれば10個のときもあるのです。 つまり、毎回各配列の数を数えて、hairetuの要素数が多いものを基準に、小さいものと比べるという処理もいるのだと考えているのです。 並び替えずに、hairetu3をいつも一番外のループにしてしまうと、条件3で検索した結果がヒット数0であり、hairetu1(条件1で絞り込んだ結果数)とhairetu4(条件4で絞り込んだ結果数)での場合、hairetu3に格納されたidが0個のため、ループが走らないのです。

すると、全ての回答が全文表示されます。

関連するQ&A