質問をすることでしか得られない、回答やアドバイスがある。

15分調べてもわからないことは、質問しよう!

ただいまの
回答率

90.34%

  • PHP

    21336questions

    PHPは、Webサイト構築に特化して開発されたプログラミング言語です。大きな特徴のひとつは、HTMLに直接プログラムを埋め込むことができるという点です。PHPを用いることで、HTMLを動的コンテンツとして出力できます。HTMLがそのままブラウザに表示されるのに対し、PHPプログラムはサーバ側で実行された結果がブラウザに表示されるため、PHPスクリプトは「サーバサイドスクリプト」と呼ばれています。

PHP foreachの中にfor文を入れた際の連想配列のキーについて

解決済

回答 2

投稿 編集

  • 評価
  • クリップ 0
  • VIEW 290

teaAI

score 8

        $setPositionPercentage =['upper'=>21, 'middle'=>67, 'low'=>14];

        if(array_sum($setPositionPercentage) > 100){
            foreach($setPositionPercentage as $key => $val){
                for ($i=100; $i<array_sum($setPositionPercentage); $i++){
                    $setPositionPercentage[$key] += -1;
                }
            }
        }
        var_dump($setPositionPercentage);
        /*
          array:3 [▼
            "upper" => 20.0
            "middle" => 66.0
            "low" => 14.0
          ]
       */

上記のvardumpの結果から、何故 "upper","middle"のkeyに対して、-1されているのでしょうか?
上記のループ、foreachの入れ子のロジックでは、upperのkeyの値に対してのみ-1ずつされていき、100になったらループを抜けると解釈していたため、何故forのループ中に、$keyが"upper"から"middle"になるのかわかりません。
返り値として、下記を想定していました。
/*
array:3 [▼
"upper" => 19.0
"middle" => 67.0
"low" => 14.0
]
*/

  • 気になる質問をクリップする

    クリップした質問は、後からいつでもマイページで確認できます。

    またクリップした質問に回答があった際、通知やメールを受け取ることができます。

    クリップを取り消します

  • 良い質問の評価を上げる

    以下のような質問は評価を上げましょう

    • 質問内容が明確
    • 自分も答えを知りたい
    • 質問者以外のユーザにも役立つ

    評価が高い質問は、TOPページの「注目」タブのフィードに表示されやすくなります。

    質問の評価を上げたことを取り消します

  • 評価を下げられる数の上限に達しました

    評価を下げることができません

    • 1日5回まで評価を下げられます
    • 1日に1ユーザに対して2回まで評価を下げられます

    質問の評価を下げる

    teratailでは下記のような質問を「具体的に困っていることがない質問」、「サイトポリシーに違反する質問」と定義し、推奨していません。

    • プログラミングに関係のない質問
    • やってほしいことだけを記載した丸投げの質問
    • 問題・課題が含まれていない質問
    • 意図的に内容が抹消された質問
    • 広告と受け取られるような投稿

    評価が下がると、TOPページの「アクティブ」「注目」タブのフィードに表示されにくくなります。

    質問の評価を下げたことを取り消します

    この機能は開放されていません

    評価を下げる条件を満たしてません

    評価を下げる理由を選択してください

    詳細な説明はこちら

    上記に当てはまらず、質問内容が明確になっていない質問には「情報の追加・修正依頼」機能からコメントをしてください。

    質問の評価を下げる機能の利用条件

    この機能を利用するためには、以下の事項を行う必要があります。

質問への追記・修正、ベストアンサー選択の依頼

  • mts10806

    2018/07/23 16:44

    途中echoなどで値を追ってデバッグしてみては?

    キャンセル

回答 2

+3

2週目でfor文の条件を満たさなくなりますね

foreach($setPositionPercentage as $key => $val){
    // (1週目)$i = 100 array_sum($setPositionPercentage) = 102  (2週目) $i=101  array_sum($setPositionPercentage) = 101
    for ($i=100; $i<array_sum($setPositionPercentage); $i++){ 
      $setPositionPercentage[$key] += -1; // (1週目)array_sum($setPositionPercentage) = 101 (2週目)通らない
    }
}

投稿

  • 回答の評価を上げる

    以下のような回答は評価を上げましょう

    • 正しい回答
    • わかりやすい回答
    • ためになる回答

    評価が高い回答ほどページの上位に表示されます。

  • 回答の評価を下げる

    下記のような回答は推奨されていません。

    • 間違っている回答
    • 質問の回答になっていない投稿
    • スパムや攻撃的な表現を用いた投稿

    評価を下げる際はその理由を明確に伝え、適切な回答に修正してもらいましょう。

checkベストアンサー

+2

foreachの入れ子のロジックでは、upperのkeyの値に対してのみ-1ずつされていき、100になったらループを抜ける

の解釈が間違っています。

for ($i=100; $i<array_sum($setPositionPercentage); $i++){
 //中身は省略
}


は、

$iを100から初めて、$iがarray_sum($setPositionPercentage)よりも小さい間処理をする

としか書かれていないです。

array_sum($setPositionPercentage)の減り方と、
for文のループの仕方を照らし合わせれば、今の結果になるのも納得できるはず・・・。


今のコードを再利用して

upperのkeyの値に対してのみ-1ずつされていき、100になったらループを抜ける

を実現するなら、せめてこう・・・

foreach($setPositionPercentage as $key => $val){
    if($key != 'upper'){
        continue;
    }
    for ($i=array_sum($setPositionPercentage); $i>100; $i--){
        $setPositionPercentage[$key] += -1;
    }
}

そもそもの話をすると、更新したいキーが固定であるならば、
外側のforeach自体が不要で、もっと単純に書いた方が分かりやすいです。

for文

$key = 'upper';
for ($i=array_sum($setPositionPercentage); $i>100; $i--){
    $setPositionPercentage[$key] += -1;
}

whileの方がコードはちょっと短くなりますね。

$key = 'upper';
while(array_sum($setPositionPercentage) > 100){
    $setPositionPercentage[$key] += -1;
}

★おまけ★
仮に、キーがランダムで、「最初のキーだけ」-1していくようにしたいならば
キーの指定はこういうことも可能です。

//連想配列の最初のキーを取得
$key = key(reset($setPositionPercentage));

投稿

  • 回答の評価を上げる

    以下のような回答は評価を上げましょう

    • 正しい回答
    • わかりやすい回答
    • ためになる回答

    評価が高い回答ほどページの上位に表示されます。

  • 回答の評価を下げる

    下記のような回答は推奨されていません。

    • 間違っている回答
    • 質問の回答になっていない投稿
    • スパムや攻撃的な表現を用いた投稿

    評価を下げる際はその理由を明確に伝え、適切な回答に修正してもらいましょう。

15分調べてもわからないことは、teratailで質問しよう!

  • ただいまの回答率 90.34%
  • 質問をまとめることで、思考を整理して素早く解決
  • テンプレート機能で、簡単に質問をまとめられる

同じタグがついた質問を見る

  • PHP

    21336questions

    PHPは、Webサイト構築に特化して開発されたプログラミング言語です。大きな特徴のひとつは、HTMLに直接プログラムを埋め込むことができるという点です。PHPを用いることで、HTMLを動的コンテンツとして出力できます。HTMLがそのままブラウザに表示されるのに対し、PHPプログラムはサーバ側で実行された結果がブラウザに表示されるため、PHPスクリプトは「サーバサイドスクリプト」と呼ばれています。