配列の計算(PHP)

このQ&Aのポイント
  • PHPで配列の計算を行う方法を教えてください
  • 配列に含まれる要素の計算式を作成し、全ての要素を足し合わせる方法を知りたいです
  • 同じ要素同士の計算方法も教えてください
回答を見る
  • ベストアンサー

配列の計算(PHP)

(1)[m1,14,5,3] (2)[m1,14,3,5] (3)[m2,28,1,30] (4)[m1,28,2,10]     ・     ・     続く     ・ このような配列を、[a,b,c,d]とします。 c*d/10を五捨五超入してから、bをかけて((1)なら1.5=1、1*14=14)、(1)~全てを足し合わせるという作業が基本で、【その中でも、aとbが同じもの同士(上記で言う(1)と(2))の場合だけは、それぞれのc*d/10を足しあわせてから五捨五超入してbをかける((1)と(2)なら1.5+1.5=3、3*14=42)】 この計算式をphpで作ろうと思っていますが、思いつきません。。。 わかる方おりましたら、ご教授よろしくおねがいします。

  • axial
  • お礼率50% (5/10)
  • PHP
  • 回答数5
  • ありがとう数1

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

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

よく見たら自分の打ち間違えが少し(cd→ch……何故こうなったし) /************************************************************************************* この配列を$multiArrayとして、 $a1=array( 0=>Array([0]=>"m1",[1]=>14,[2]=>5,[3]=>3) ,1=>Array([0]=>"m1",[1]=>14,[2]=>3,[3]=>5) ,2=>Array([0]=>"m2",[1]=>28,[2]=>1,[3]=>30) ,3=>Array([0]=>"m1",[1]=>28,[2]=>2,[3]=>10) ); $data[0]=m1・・・とforeachで取り出して、$data=array(m1,m1,m2,m1)を作ってmultiArrayを$dataで並び替え(m1,m1,m1,m2) *************************************************************************************/ 配列の格納はご想像通りです /************************************************************************************* cdの計算を先に行なって配列に格納,cdflash=[1.5,1.5,3,2] 次の$wkSinArr = array($mulchArray[0]);は配列に配列を格納したもので、$wkSinArr[0]はArray([0]=>"m1",[1]=>14,[2]=>5,[3]=>3)という配列を取り出しているということになるのでしょうか? そう考えると$wkSinArr[0] == $mulchArray[$x][0] はArray([0]=>"m1",[1]=>14,[2]=>5,[3]=>3)="m1"となって完全に手詰まりになってしまいます・・・。 *************************************************************************************/ どう解釈されているのかわからないですが if($wkSinArr[0] == $mulchArray[$x][0] && $wkSinArr[1] == $mulchArray[$x][1])で 最初に比較対象として保存した一時配列wkSinArr[0]はmulchArray[0][0]と同じです if内では[0]要素と[1]要素がmulchArrayの次の物と同じであればcdの計算を合計します ただし違う物であった場合、合計した物をbでかけて、現在参照している違う物を比較対象として保存します "&&"は「○○且つ(チェック)(チェック)」の様にANDの意味合いです(知っているとは思いますが) /************************************************************************************* $wkSinArr[0] が"m1"であれば、m1である間は$wk1が足されて、上記でいう4番目のm2にきたときにelse文に移動して、五捨六入されて、"14"をかけて$singleArray[]にいれ、新しい行のデータに更新後、繰り返し、最後に$singleArray[]の数値を足し合わせるという事になりわかる気がします。 *************************************************************************************/ 3番目で要素[1]が違うので否となり要素[2]と[3]は別計算となります /************************************************************************************* ちなみに、五捨五超入は、1.49999は1、1.5は1、1.51は2、1.5000000001は2というもので、桁数が無限だとわからないですが、桁数が10桁とか指定してしまえば、 for($ii=1;$ii<10;$ii++){ //小数点以下は10桁まではカウント if(strlen($cpricearray[1])==$ii){ $keta=pow(10,$ii-1);//10の何乗 if($cpricearray[1] > 5*$keta){ $kuri=1; }else{ $kuri=0; } のような形で無理やり計算できていました。 *************************************************************************************/ 許容する桁数が分からないかったですがそうなると 「$wk1 = round($wk1, 0, PHP_ROUND_HALF_DOWN);」が //丸めたい桁数から繰り上げていく、少数第一位にまで繰り上げ for($cnt = 10;$cnt >= 1;$cnt--){ $wk1 = round($wk1,$cnt); } //全て繰り上げた結果がn.6以上なら少数を繰り上げ $wk1 = round($wk1, 0, PHP_ROUND_HALF_DOWN); になるかと 自分の回答は全て未検証なのでコピペではなく自分で理解して 望むソースに変更して頂けくと尚の事よろしいかと思います(わからないことは答えますので)

axial
質問者

お礼

何度かいじくっているうちに分かって来ました。ソースも使わせて頂き、無事期待したプログラムを組むことができました。本当に感謝しております。

その他の回答 (4)

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

こんな感じかなぁ・・・作業用テーブルの$a2を見てもらえば だいたいイメージがわくと思います <?PHP function roundx( $val ) { if($val - (int) $val <=0.5){ return floor($val); }else{ return ceil($val); } } $a1=array( 1=>Array("a"=>"m1","b"=>14,"c"=>5,"d"=>3) ,2=>Array("a"=>"m1","b"=>14,"c"=>3,"d"=>5) ,3=>Array("a"=>"m2","b"=>28,"c"=>1,"d"=>30) ,4=>Array("a"=>"m1","b"=>28,"c"=>2,"d"=>10) ,5=>Array("a"=>"m3","b"=>13,"c"=>3,"d"=>3) ,6=>Array("a"=>"m3","b"=>13,"c"=>5,"d"=>3) ,7=>Array("a"=>"m3","b"=>13,"c"=>6,"d"=>6) ,8=>Array("a"=>"m1","b"=>14,"c"=>9,"d"=>9) ); $a2=array(); foreach($a1 as $b1){ foreach($a2 as $key=>$b3){ if($b3["a"]===$b1["a"] and $b3["b"]===$b1["b"]){ $b2=&$a2[$key]; break; } } if(!isset($b2)){ $b2=&$a2[]; $b2["a"]=$b1["a"]; $b2["b"]=$b1["b"]; $b2["amount_c_by_d"]=0; } $b2["amount_c_by_d"]+=$b1["c"]*$b1["d"]; unset($b2); } print_r($a2); $total=0; foreach($a2 as $b3){ $total+=$b3["b"]*roundx($b3["amount_c_by_d"]/10); } print $total; ?>

axial
質問者

補足

>yambe.jp様 先の説明不足について改めてお詫びいたします。 最近始めたばかりということもあり理解に時間がかかっております。(初めて見る演算子が多いのもあります。。。) foreach($a2 as $key=>$b3){の部分から既についていけません。$a2は空の配列なのにas以下に代入できるのでしょうか? とすると、$b3から始まるif($b3["a"]===$b1["a"] and $b3["b"]===$b1["b"]){もわからず、$b2=&$a2[$key];や$b2=&$a2[];の”=&”の意味もわからず・・・。 amount_c_by_dというのは何者なのでしょうか? コピー・ペーストで期待の数値が問題なく算出されるため、プログラムは大丈夫そうです。

回答No.3

ようやく噛み砕けました・・・ 前述の多次元ループに二次元目が不必要だったのでソレも踏まえて修正 //同じ物を比較する為、先に比較対象でソートする foreach($mulchArray as $key => $row){ $data[$key] = $row[0]; } array_multisort($data,SORT_DESC,$mulchArray); //CDの計算を先に全て行う $cdFlash = array(); for($x=0;$x<count($mulchArray);$x++){ //計算1 $wk1 = $mulchArray[$x][2] * $mulchArray[$x][3] / 10; $cdFlash[] = $wk1; } $singleArray = array(); //比較情報 $wkSinArr = array($mulchArray[0]); $wk1 = cdFlash[0]; for($x=1;$x<count($mulchArray);$x++){ if($wkSinArr[0] == $mulchArray[$x][0] && $wkSinArr[1] == $mulchArray[$x][1]){ $wk1 = $wk1 + $cdFlash[$x]; }else{ //少数第一位で五捨六入 $wk1 = round($wk1, 0, PHP_ROUND_HALF_DOWN); //計算2 $singleArray[] = $wk1 * $wkSinArr[1]; //比較情報を更新 $wk1 = chFlash[$x]; $wkSinArr = array($mulchArray[$x]); } } $total = $singleArray[0]; for($n=1;$n < count($singleArray);$n++){ $total = $total + $singleArray[$n]; } echo $total;

axial
質問者

補足

>CyberCypher様 最近始めたばかりということもあり理解に時間がかかっております。 この配列を$multiArrayとして、 $a1=array( 0=>Array([0]=>"m1",[1]=>14,[2]=>5,[3]=>3) ,1=>Array([0]=>"m1",[1]=>14,[2]=>3,[3]=>5) ,2=>Array([0]=>"m2",[1]=>28,[2]=>1,[3]=>30) ,3=>Array([0]=>"m1",[1]=>28,[2]=>2,[3]=>10) ); $data[0]=m1・・・とforeachで取り出して、$data=array(m1,m1,m2,m1)を作ってmultiArrayを$dataで並び替え(m1,m1,m1,m2) cdの計算を先に行なって配列に格納,cdflash=[1.5,1.5,3,2] 次の$wkSinArr = array($mulchArray[0]);は配列に配列を格納したもので、$wkSinArr[0]はArray([0]=>"m1",[1]=>14,[2]=>5,[3]=>3)という配列を取り出しているということになるのでしょうか? そう考えると$wkSinArr[0] == $mulchArray[$x][0] はArray([0]=>"m1",[1]=>14,[2]=>5,[3]=>3)="m1"となって完全に手詰まりになってしまいます・・・。 $wkSinArr[0] が"m1"であれば、m1である間は$wk1が足されて、上記でいう4番目のm2にきたときにelse文に移動して、五捨六入されて、"14"をかけて$singleArray[]にいれ、新しい行のデータに更新後、繰り返し、最後に$singleArray[]の数値を足し合わせるという事になりわかる気がします。 ちなみに、五捨五超入は、1.49999は1、1.5は1、1.51は2、1.5000000001は2というもので、桁数が無限だとわからないですが、桁数が10桁とか指定してしまえば、 for($ii=1;$ii<10;$ii++){ //小数点以下は10桁まではカウント if(strlen($cpricearray[1])==$ii){ $keta=pow(10,$ii-1);//10の何乗 if($cpricearray[1] > 5*$keta){ $kuri=1; }else{ $kuri=0; } のような形で無理やり計算できていました。 コピー貼り付けで"["エラーがでてしまって実行結果が見れなかったのですが、これで動きそうだと思います。 上記のわからない部分を教えていただけたら幸いです。

回答No.2

二次元配列が複数あるという事ですか? それとも多次元配列に入れているということですか? 見てる限り多次元配列がベストだと思うのでソレを想定します あと要素0(a)は計算とは別情報ですよね? ちょっと何がしたいか良く分からないですが 簡潔に言うと 1.各要素のc*d/10を五捨六入し、bをかける 2.各要素の計算結果を足し合わせる 以上でいいんですよね? 【】内に一番混乱しているのですが…… $singleArray = array(); for($x=0;$x<count($mulchArray);$x++){ for($y=0;$y<count($mulchArray[$x]);$y++){ //計算1 $wk1 = $mulchArray[$x][2] * $mulchArray[$x][3] / 10; //少数第一位で五捨六入 $wk1 = round($wk1, 0, PHP_ROUND_HALF_DOWN); //計算2 $wk1 = $wk1 * $mulchArray[$x][1]; singleArray[] = $wk1; } } $total = $singleArray[0]; for($n=1;$n < count($singleArray);$n++){ $total = $total + $singleArray[$n]; } echo $total;

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

仕様の提示があいまいすぎて、回答しようがありません。 結局結果をどうしたいのでしょう?順番に表示すればよいの? なにか別の配列に戻してやりたいの? また、出現の順番は保証されているの?その場合a,bが一緒の データとは隣り合ったデータに限られるの?離れていても探し出すの? 離れた値を表示する場合の戻り値の順序はどうなるの? 2データを1つにするにあたっては集約結果をどう表現したいの? それと同じデータというのは2つしか出現しないの? 3つ以上出現する場合は計算根拠はどうなるの? <?PHP $a=array( 1=>Array("a"=>"m1","b"=>14,"c"=>5,"d"=>3) ,2=>Array("a"=>"m1","b"=>14,"c"=>3,"d"=>5) ,3=>Array("a"=>"m2","b"=>28,"c"=>1,"d"=>30) ,4=>Array("a"=>"m1","b"=>28,"c"=>2,"d"=>10) ); print_r($a); ?> と、なっているとして、具体的に得たいものはいったいなんでしょう?

axial
質問者

補足

具体的に欲しいデータは、この例だと4つの配列なので、 (5*3/10+3*5/10)*14=42 1*30/10*28=84 2*10/10*28=56 全てを合計して、182が得たいデータとなります。 フォーム入力からの$_POSTデータの受け取りのため、実際の配列は4つ以上のこともあるし、1つのこともあります。 つまり、フォーム画面に4つのinputがあって 1行目:$_POST['a1']="m1"、$_POST['b1']="14"、$_POST['c1']="5"、$_POST['d1']="3" 2行目:$_POST['a2']="m1"、$_POST['b2']="14"、$_POST['c2']="3"、$_POST['d2']="5" 3行目:略  ・  ・ のように別のページに値を引渡し、その値を上記例では配列に格納、上記の計算式にて合計を算出するといったものです。 ですので、出現の順番は保証されています。abが一緒のデータとは隣り合ったデータに限られます。離れた値を表示する場合の戻り値の順序は、合計がわかればいいので気にしません。2データを1つにするにあたっては、個別に五捨五超入してから足し合わせるのと、足してから五捨五超入するので値が違うのでせざるを得ないだけで、合計がほしいのです。同じデータは2つかもしれませんし、1つかもしれませんし、3つかもしれません、フォーム入力データにより異なります。 3つ以上出現する場合は、 1=>Array("a"=>"m1","b"=>14,"c"=>5,"d"=>3) ,2=>Array("a"=>"m1","b"=>14,"c"=>3,"d"=>5) ,3=>Array("a"=>"m2","b"=>28,"c"=>1,"d"=>30) ,4=>Array("a"=>"m1","b"=>14,"c"=>2,"d"=>10) ←bが14の場合 (5*3/10+3*5/10+2*10/10)*14=70 1*30/10*28=84 で合計は154となって、これが欲しい値となります。 わかりにくいですが、よろしくお願い致します。

関連するQ&A

  • PHPの配列について

    PHPの配列についての質問です。 以下のソースを // == ソース == function hoge( $foo ) { $arrs['a'] = 'A'. $foo; $arrs['b'] = 'B'. $foo; $arrs['c'] = 'C'. $foo; $arrs['d'] = 'D'. $foo; } hoge( '3' ); hoge( '9' ); // == /ソース == 実行すると print_rは // == print_r == Array (   [a] => A3   [b] => B3   [c] => C3   [d] => D3 ) Array (   [a] => A9   [b] => B9   [c] => C9   [d] => D9 ) // == /print_r == のようになります。 これを 関数を実行するごとに (0から IDのような 配列を組むようにする) 以下のようにするには どのようにすればよいでしょうか? // == print_r == Array (   [0] => Array     (       [a] => A3       [b] => B3       [c] => C3       [d] => D3     )   [1] => Array     (       [a] => A9       [b] => B9       [c] => C9       [d] => D9     ) ) // == /print_r == 使用目的は get_contentsしたものを正規表現で取り出し 配列にする処理に使おうと思っています。

    • ベストアンサー
    • PHP
  • PHPの配列でわからないことがあるので教えてください。

    PHPの配列でわからないことがあるので教えてください。 例えば以下のような2つの配列$aと$bがあるとします。 $a[0]=a、$a[1]=b、$a[2]=c $b[0]=w、$b[1]=q、$b[2]=b、$b[3]=c これで、$a[1]と$b[2]の中身が同じであることを取得し、さらに$bの配列の添え字の2を返すようにしたいのですが、わかりません。 どのようにプログラムを書けばよいのでしょうか? よろしくお願いします。

    • ベストアンサー
    • PHP
  • 配列数式で平均を出すと空欄が0で計算されてしまう

      A B C D 1  1 2 1 {=AVERAGE(IF($A$1:$A$4=$C1,B$1:B$4))} 2  1 4 2 {=AVERAGE(IF($A$1:$A$4=$C2,B$1:B$4))} 3  2 6 4  2 8 上記のような数値、数式ですと、 B列すべてに数値が入力されているため、問題なく計算するのですが、 例えば、B2のセルを空欄にすると、空欄を0としてしまい、 D1の計算結果が1となってしまいます。 D1の数式を=AVERAGE(B1:B2)としますと、空欄は空欄として扱い、 計算結果は2となります。 配列数式を使った場合にも、空欄を空欄として扱い、 計算結果が2となるような方法はありませんでしょうか。 よろしくお願いします。

  • VBAで配列の計算

    VBAで配列同士の計算をすることはできますか? たとえば、配列A,B,Cがあったときに C=A+Bみたいな記述はできるのでしょうか?

  • PHP 連想( 2~多次元 )配列の向き変換

    こんにちは $associative_multi_d_array = array('a'=>array('a'=>1,'b'=2),'b'=>array('a'=>1,'b'=2),'c'=>array('a'=>1,'b'=2)); ↓ 変換処理 ↓ $associative_multi_d_array = array('a'=>array('a'=>1,'b'=>1,'c'=>1),'b'=>array('a'=>2,'b'=>2,'c'=>2)); 連想( 2~多次元 )配列の向きを上記のように変更するfunctionをPHPで書いてください。 ※各階層ごと出てくる用素数は同じです。

    • ベストアンサー
    • PHP
  • 【PHP】配列を連想配列に

    $m = array('a', 'b', 'c'); この配列 $m をもとに $n = array(  'a' => array(   'b' => array(    'c' => array()))); 上のような連想配列 $n をつくりたいのですが、 $n = array(  $m[0] => array(   $m[1] => array(    $m[2] => array()))); 要素の数が固定のときは、これでもいいのですが、数が変動する場合に対応できません。 何か方法があれば教えてください。

    • ベストアンサー
    • PHP
  • PHPからFlashへの配列の渡し方がわかりません

    こんにちは。 FlashとPHPの連係についての質問です。 どうしてもわからないのでどなたか手を貸してくださると助かります。 PHP側から$a=array("a","b","c")、という配列をFlash側に送ります。 その際、まずHTMLタグの<object>内にはどのように記述すればよろしいのでしょうか? またFlash側でその配列をどのように受け取り、その値を配列に入れたいのですがどのようにしたらよろしいでしょうか?? どなたかお願いいたします。

    • ベストアンサー
    • Flash
  • PHPからFlashへの配列の渡し方がわかりません

    こんにちは。 FlashとPHPの連係についての質問です。 どうしてもわからないのでどなたか手を貸してくださると助かります。 PHP側から$a=array("a","b","c")、という配列をFlash側に送ります。 その際、まずHTMLタグの<object>内にはどのように記述すればよろしいのでしょうか? またFlash側でその配列をどのように受け取ればよろしいでしょうか?? どなたかお願いいたします。

    • 締切済み
    • PHP
  • 配列のサイズが明示的でない計算について

    Fortranを例にとった場合、 行列A,Bの積Cを計算する場合、例えば以下のようなループで計算していました。(Fortran77) do i=1,10 do j=1,10 sum=0.0 do m=1,10 sum=sum+a(i,m)*b(m,j) enddo c(i,j)=sum enddo enddo それが今では、以下1行です。(Fortran95) c=matmul(a,b) 配列1つ1つの成分について計算する必要がないと言えそうです。Pythonなんかは全部こういう思想ですね。 プログラム言語はすべてこういう方向に進んでいるように思えます。 これがやや不安に思えるところがあります。配列のサイズを指定していないのでどこまで使って計算しているかわからないからです。 古い方(上段)では配列のサイズや上限を指定しているので、指定しているところより先がどうなっていてもとりあえず被害はありません。 しかし、サイズについてのケアがないと思いがけないような計算をしてくるんじゃないかと思うのですが。計算のバグ取のときここ大丈夫かな?となって疑心暗鬼ということにならないかと思うのですが。 配列の最大値なども関数1つと言う感じですが、どこまでの範囲での最大なの?と聞きたくなるわけですが。 いかがでしょうか。

  • このような配列の場合の計算法はどうすればいいのですか?

    プログラミング言語(C言語、JavaScript、PHP)を勉強し始めたのですが、以下のような場合の計算法がわかりません。 もう2日悩んでいます…。 ■配列の中身が、3つあるとします。たとえば、array(10,20,30)とします。 このとき  printf((10*20) + (20*30) + (30*10)); という計算式の結果を求めたいです。 ■配列の中身が、4つあるとします。たとえば、array(10,20,30,40)とします。 このとき  printf((10*20*30) + (10*20*40) + (10*30*40) + (20*30*40)); という計算式の結果を求めたいです。 ■配列の中身が、5つあるとします。たとえば、array(10,20,30,40,50)とします。 このとき  printf((10*20*30*40) + (10*20*40*50) + (10*20*30*50) + (10*30*40*50) + (20*30*40*50)); という計算式の結果を求めたいです…(何度もすみません)。 上記のように配列の中身の個数と値が未確定の場合はどのようなコードで計算させればよいのでしょうか?配列の個数は1~10個を想定しております。 C言語、JavaScript、PHPのどの方法でもアプローチ法は同じだと思うので、いずれかの言語でかまいませんのでアドバイス頂ければと思います。よろしくお願いします。

専門家に質問してみよう