電子書籍の厳選無料作品が豊富!

PHP5.2.4を使用しています。

連想配列のキーが[]で囲まれている時、
その中の数字が倍数としてチェックされるとします。
次の例では、3と4の倍数の時に条件(if (is_int($wk)))に引っかかり
キーの値(3の倍数です、など)が表示されます。
ただこのやり方だと、foreachでループさせないと倍数かどうかが分からないので、
もっと効率の良い(isset($arr[$i])で調べられるような)調べ方はできないでしょうか?

$arr = array(
 '1' => '1です',
 '2' => '2です',
 '[3]' => '3の倍数です',
 '[4]' => '4の倍数です',
);
for ($i = 1; $i < 15; $i++)
{
 if (isset($arr[$i])) //←全てこの(簡単な)条件式で調べられれば良いのですが・・・
 {
  print "{$arr[$i]}<br>\n";
 }
 foreach ($arr as $key => $value)//←キーが倍数かはどうしても全てのキーをチェックせざるえない
 {
  if (preg_match("/\[(\d+)\]/", $key, $match))
  {
   $wk = $i / $match[1];
   if (is_int($wk)) //←除算した結果が整数ならその倍数だと判明
   {
    print "i={$i} {$arr[$match[0]]}<br>\n";
   }
  }
 }
}

1です
2です
i=3 3の倍数です
i=4 4の倍数です
i=6 3の倍数です
i=8 4の倍数です
i=9 3の倍数です
i=12 3の倍数です
i=12 4の倍数です
i=15 3の倍数です

A 回答 (4件)

倍数チェック用の配列 ($arr2) を前もって作成してチェックすれば isset() にてチェック可能なロジックが組めるのではと思います。

以下のようなロジックではどうでしょうか?
しかしながら、これが全ループで逐次チェックする方法に比べて計算回数が多いか少ないかは当方もわかりません。

(ロジック例)
$imax = 100;  // $i の最大値

$arr2 = array();
foreach ($arr as $key => $val)
{
 if (substr($key, 0, 1) == '[')
 {
  $num = substr($key, 1, -1);
  if ($num <= 0) { print('error'); exit; }
  $jmax = (int)($imax / $num);
  for ($j = 1; $j <= $jmax; $j ++)
  {
   $k = $j * $num; // 倍数
   if (!isset($arr2[$k])) { $arr2[$k] = array(); }
   $arr2[$k][] = $val;
  }
 }
}

for ($i = 1; $i <= $imax; $i++)
{
 if (isset($arr[$i]))
 {
  print "{$arr[$i]}<br>\n";
 }
 if (isset($arr2[$i]))
 {
  print join("<br>\n", $arr2[$i]);
 }
}
    • good
    • 0
この回答へのお礼

ご返答ありがとうございます。
なるほど、こういうやり方もあるわけですね。
確かにキーの数によるとは思いますが、
自分が示した例よりは効率が良いような気がします。

お礼日時:2008/05/28 16:41

こんなのは、どうでしょう?



<?php

$arr = array(
  '1' => '1です',
  '2' => '2です',
  '[3]' => '3の倍数です',
  '[4]' => '4の倍数です',
);

foreach($arr as $k => $v) {
  if(preg_match('/\[(\d+)\]/', $k, $m)) {
    $arrCheck[$m[1]] = $v;
  } else {
    $arrNoCheck[$k] = $v;
  }
}

for($i = 1; $i < 15; $i++) {
  if(isset($arrNoCheck[$i])) {
    echo "{$arr[$i]}<br>\n";
  } else {
    foreach($arrCheck as $k => $v) {
      if($i % $k == 0) {
        echo "i={$i} {$arrCheck[$k]}<br>\n";
      }
    }
  }
}
?>
    • good
    • 0
この回答へのお礼

ご返答ありがとうございます。
いくらかは効率が良くなっていますが、
やっぱり
>   foreach($arrCheck as $k => $v) {
を使っているということは、
ほとんどの$iに対して調べるということなので
このループを使わずにできないものでしょうか?

お礼日時:2008/05/29 18:18

倍数かどうかの判定は余りを求める剰余演算子「%」で結果が0かどうかを調べれば簡単にだせるかとおもいます。




for ($i = 1; $i < 15; $i++)
 print "i=" . $i;
 if($i % 3 == 0){
  print " 3の倍数です";
 }
 if($i % 4 == 0){
  print " 4の倍数です";
 }
 print "<br>\n";
}

参考URL:http://jp2.php.net/manual/ja/language.operators. …
    • good
    • 0
この回答へのお礼

ご返答ありがとうございます。
確かにそうなんですが、3の倍数か5の倍数か8の倍数か
どの倍数がその配列にセットされてるかは分からなくて
それを調べるという作業をやりたいのです。
saintandreさんのやり方だと、
3の倍数がキーにセットされてるか調べる時は
 if($i % 3 == 0){
  print " 3の倍数です";
 }
4の倍数がキーにセットされてるか調べる時は
 if($i % 4 == 0){
  print " 4の倍数です";
 }
とその都度書き足さないといけなくて、
ではループなら自分が示した例(
QNo.4051581のforeach ($arr as $key => $value)//←キーが倍数かはどうしても全てのキーをチェックせざるえない
)のように一つにまとめて書くことができるのですが、
それは効率が悪そうなのでやりたくないのです・・・
できれば、1や4など(つまり倍数としてじゃなく)を調べる
if (isset($arr[$i]))
のようにループを使わずにそのキーがセットされてるか調べたいのですが
このようなことは可能なのでしょうか?

お礼日時:2008/05/27 15:39

gmpライブラリでソースを簡略化できるかもしれません



http://www.php.net/manual/ja/book.gmp.php

ちなみに命題があいまいでよくわからないのですが・・・
これは素数以外のデータをとりたいということでしょうか?
そうなると3は素数ですが、3は3の倍数というのが理解できません。
4は2の倍数ですよね?14は2の倍数ですがよろしいのでしょうか?
    • good
    • 0
この回答へのお礼

ご返答ありがとうございます。
すいません、
自分も内容の説明もそうですが、どういう題名をつけるべきか迷いました・・・

http://www.php.net/manual/ja/book.gmp.php
見てみたのですが、この中にはなさそうだと思うのですが、、
何か使えるのはあるのでしょうか?

これは素数とかは関係なくて、
$iの値が
3の倍数なら3,6,9,12・・・
4の倍数なら4,8,12,16・・・
となったときに、そのキーの$arrがセットされてるか値を調べたいのです。
単にキーが1とか3なら
if (isset($arr[$i]))
で値がセットされてるか調べられますよね。
だけど、5の倍数の時を調べたいとなると、
if (isset($arr[$i]))
↑このやり方だと、$iがループしてきて5の時は調べられますけど
次の10や15のときはこのままの条件式だと無理ですよね?
でもだからといってforeachを使ってまた全部のキーを調べるやり方は
効率が悪いのでやりたくないです。

お礼日時:2008/05/26 18:51

お探しのQ&Aが見つからない時は、教えて!gooで質問しましょう!