• ベストアンサー
※ ChatGPTを利用し、要約された質問です(原文:配列の計算(PHP))

配列の計算(PHP)

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

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

  • ベストアンサー
回答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