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

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

新規登録して質問してみよう
ただいま回答率
85.48%
PHP

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

Q&A

解決済

3回答

696閲覧

PHPの配列で、キーが同じだとループ内で配列が追加されないときはどうすればいいですか?

kannmuri

総合スコア42

PHP

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

0グッド

0クリップ

投稿2019/05/31 03:36

編集2019/05/31 03:51

###前提・実現したいこと

以下のように「$rand」というキーで配列が作られ、「'追加'」を追加しています。

しかし「$rand」の値が同じとき、2回目以降のループで「'追加'」が追加されなくなってしまいます。

これを解決したいです。

PHP

1 2function getrand(){ 3 $rand = str_shuffle('AB'); 4 return $rand; 5} 6 7$add = 'on'; 8 9$ar = []; 10 11$i = 0; 12while($i < 3){ 13 14 $rand = getrand(); 15 16 $ar['fruits'][$rand][] = [ 17 'name' => 'apple', 18 'color' => 'red' 19 ]; 20 21 if( $add == 'on' ){ 22 $ar['fruits'][$rand][0]['add'] = '追加'; // これが1回しか追加されない 23 } 24 25 $i++; 26} 27 28var_dump($ar);

###実際の例
たとえば上を実行して次の配列が得られたときに、["AB"]の配列を見てみてください。

[0]には「'追加'」が追加されていますが、
[1]には追加されなくなるということです。
そして["BA"]の配列には追加されています。

これが冒頭に書いた、「$rand」の値が同じとき、2回目以降のループで「'追加'」が追加されなくなる。という現象です。

PHP

1array(1) { 2 ["fruits"]=> 3 array(2) { 4 ["AB"]=> 5 array(2) { 6 [0]=> 7 array(3) { 8 ["name"]=> 9 string(5) "apple" 10 ["color"]=> 11 string(3) "red" 12 ["add"]=> 13 string(6) "追加" 14 } 15 [1]=> 16 array(2) { 17 ["name"]=> 18 string(5) "apple" 19 ["color"]=> 20 string(3) "red" 21 } 22 } 23 ["BA"]=> 24 array(1) { 25 [0]=> 26 array(3) { 27 ["name"]=> 28 string(5) "apple" 29 ["color"]=> 30 string(3) "red" 31 ["add"]=> 32 string(6) "追加" 33 } 34 } 35 } 36}

2回目以降のループにも「'追加'」を追加したいときは、どうしたらいいのでしょうか?(ちなみにwhileのループ数は上の例では3回ですが、実際には未定です。)

###どういう結果にしたいのか
を補足させていただきますと、こんな感じの配列にしたいです。上の配列と比べて「これ」の部分が変わっているのがわかるかと思います。
(ただし配列はランダムに生成されるなので、あくまで上の配列の場合ならこうしたい、という例です。)

PHP

1array(1) { 2 ["fruits"]=> 3 array(2) { 4 ["AB"]=> 5 array(2) { 6 [0]=> 7 array(3) { 8 ["name"]=> 9 string(5) "apple" 10 ["color"]=> 11 string(3) "red" 12 ["add"]=> 13 string(6) "追加" 14 } 15 [1]=> 16 array(3) { 17 ["name"]=> 18 string(5) "apple" 19 ["color"]=> 20 string(3) "red" 21 ["add"]=>   // これ 22 string(6) "追加" // これ 23 } 24 } 25 ["BA"]=> 26 array(1) { 27 [0]=> 28 array(3) { 29 ["name"]=> 30 string(5) "apple" 31 ["color"]=> 32 string(3) "red" 33 ["add"]=> 34 string(6) "追加" 35 } 36 } 37 } 38}

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

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

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

バッドをするには、ログインかつ

こちらの条件を満たす必要があります。

m.ts10806

2019/05/31 03:40

どういう結果にしたいのか具体的に記載してください(できればvar_dump()かvar_export()で出力される形式に) 法則がちゃんとあるのでしたら効率的なやりかたも可能ですが、それが見いだせるかどうかは仕様次第で、なければ直接的に入れるしかありません(前の質問の私の回答が例。あれでも法則性はあるので別回答の通りにもできる)
guest

回答3

0

php

1<?php 2function getrand(){ 3 $rand = str_shuffle('AB'); 4 return $rand; 5} 6 7$add = 'on'; 8 9$ar = []; 10 11$i = 0; 12while($i < 3){ 13 14 $rand = getrand(); 15 16 $adder = [ 17 'name' => 'apple', 18 'color' => 'red' 19 ]; 20 if( $add == 'on' ){ $adder['add'] = '追加';} 21 22 $ar['fruits'][$rand][] = $adder; 23 24 $i++; 25} 26 27var_dump($ar);

だって、「whileの中の配列の0個目」じゃないですか?なら、

$ar['fruits'][$rand][0]
じゃないんでしょうか?

shuffleは2種類の値しかとらないので、$iが2のとき$randが"AB"でも"BA"でも既に追加がおきており、少なくとも2番目(配列インデクスで言えば"1"個目)であり、0個目ではないです。

投稿2019/05/31 04:11

papinianus

総合スコア12705

バッドをするには、ログインかつ

こちらの条件を満たす必要があります。

papinianus

2019/05/31 04:17 編集

whileの中で、という話ですが、$arはwhileの外で宣言されているので「中」というのが微妙ですし、phpはそんなブロックスコープもたないですし、while内部は3回実行しているので、常に0個目だという発想は誤解があると思います。 また、質問は「1回しか実行されない」ですが、実際にはphpはその代入を3回やっていますので、おっしゃる「0個目」への代入が3回発生しています。 こうなって欲しい姿がそもそも配列のインデクスでいう1個目への書き込みなので、0個目に代入という処理を書いてそれが実現できるはずがないですよね
kannmuri

2019/05/31 04:19

なんとなく…たしかに。ありがとうございます。
guest

0

どうしたいのかは確認中なので「同じキーの時」を判定するヒントだけ。
・array_key_exists()

結局は前の質問と同じで

$ar['fruits'][$rand][0]['add'] = '追加'; // これが1回しか追加されない

太字にしたところ、固定にしているからです。
$変数名[] で入れると結果の通り「キーを0から順番に」値を作っていきます。
つまり0を固定で指定しているかぎり、最初の配列にしか値は作られません。

$iが0始まりでカウントアップしているなら明示的にキーを指定してあげると良いです。

php

1 $ar['fruits'][$rand][$i] = [ 2 'name' => 'apple', 3 'color' => 'red' 4 ]; 5 6 if( $add == 'on' ){ 7 $ar['fruits'][$rand][$i]['add'] = '追加'; 8 } 9

投稿2019/05/31 03:46

編集2019/05/31 03:57
m.ts10806

総合スコア80850

バッドをするには、ログインかつ

こちらの条件を満たす必要があります。

kannmuri

2019/05/31 04:06

「0を固定で指定している」のはまさにって感じなんですけど、いやだってだって、「whileの中の配列の0個目」じゃないですか?って思ってます。なんでいけないんですか?? 「whileの外の配列」に追加するのなら、それは確かにカウントアップしないといけないでしょうけど、 でもwhileの中で生成された配列が追加対象なんですから、そりゃ、「0個目」しか存在しないと思ってるんですけど、んーー泣きそうですw
m.ts10806

2019/05/31 04:20 編集

中とか外とか関係ないですよ。 だって配列自体はwhileの外で定義されているし、そもそもPHPの変数はfunctionやクラスなどを挟んでない単なるグローバルスコープ上なら定義して以降そのまま有効です。 プログラムは書いた通りに動きます。書いた人の思った通りに動くわけじゃないですよ。 var_dump()で出力されているなら結果全てです。 どんなにやっても["fruits"]の['AB']の[0]には1つ目のappleしか入ってません。 質問者さんがやっているのは下記と同じです。 $a = []; $a[] = 1; $a[] = 1; $a[] = 1; $a[] = 1; $a[0] = 2;
kannmuri

2019/05/31 04:22

中とか外とか関係あると思ってました。最後の例なるほど。でも思った通りに動いてほしい!w
m.ts10806

2019/05/31 04:24

思った通りに動かそうと思ったらかなりの経験と知識が必要です。設計する力も必要でしょう。 ただ、それでも思ったように動かないからみんなデバッグをして調査検証していくのです。
kannmuri

2019/05/31 04:32

上位ランカーさまでもそういうもんですか。ありがとです。ガンバリマス!
m.ts10806

2019/05/31 04:37

「書いた通りにしか動かない」という意識を常に持つことで想定通り動かない→デバッグ(あとマニュアル確認)と自然に頭が向くようになります。 たぶん、それだけの違いです。
guest

0

ベストアンサー

$ar['fruits'][$rand][0]

を指定しているからですね

PHP

1function getrand(){ 2 $rand = str_shuffle('AB'); 3 return $rand; 4} 5$add = 'on'; 6$ar = []; 7$i = 0; 8while($i < 3){ 9 $rand = getrand(); 10 $ar['fruits'][$rand][] = [ 11 'name' => 'apple', 12 'color' => 'red' 13 ]; 14 if( $add == 'on' ){ 15 $ar['fruits'][$rand][count($ar['fruits'][$rand])-1]['add'] = '追加'; 16 } 17 $i++; 18} 19var_dump($ar);

とするか、リファレンスを使います。

PHP

1function getrand(){ 2 $rand = str_shuffle('AB'); 3 return $rand; 4} 5$add = 'on'; 6$ar = []; 7$i = 0; 8while($i < 3){ 9 $rand = getrand(); 10 $temp=&$ar['fruits'][$rand][]; 11 $temp=[ 12 'name' => 'apple', 13 'color' => 'red' 14 ]; 15 if( $add == 'on' ){ 16 $temp['add'] = '追加'; 17 } 18 $i++; 19} 20unset($temp);//使い終わったら必ず削除すること 21var_dump($ar);

投稿2019/05/31 03:54

yambejp

総合スコア114843

バッドをするには、ログインかつ

こちらの条件を満たす必要があります。

kannmuri

2019/05/31 04:03 編集

ミラクルパーフェクトです。ありがとうございます!!でもなんで質問のコードでできないのか、まだよくわかりませんw だって、「whileの中の配列の0個目」じゃないですか?なら、 $ar['fruits'][$rand][0] じゃないんでしょうか? どうして $ar['fruits'][$rand][count($ar['fruits'][$rand])-1]['add'] になるんですか??なぞです。 p.s. 「リファレンス」とやらの方は難しいのでスルーさせてくださいwブクマしといたのでいずれじっくり勉強します。(。-人-。)
yambejp

2019/05/31 04:23

$ar['fruits'][$rand][0]は$ar['fruits'][$rand]配列にある最初の要素なので その次に追加された$ar['fruits'][$rand][1]へのデータ投入には使えません
kannmuri

2019/05/31 04:31

なんとなくわかってきました。ありがとうございます。これから気を付けます!
guest

あなたの回答

tips

太字

斜体

打ち消し線

見出し

引用テキストの挿入

コードの挿入

リンクの挿入

リストの挿入

番号リストの挿入

表の挿入

水平線の挿入

プレビュー

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

ただいまの回答率
85.48%

質問をまとめることで
思考を整理して素早く解決

テンプレート機能で
簡単に質問をまとめる

質問する

関連した質問