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

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

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

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

Q&A

解決済

1回答

191閲覧

PHPの配列連結で、連結される位置が目的のようにならず困っています

love_kinniky

総合スコア22

PHP

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

0グッド

0クリップ

投稿2019/05/22 11:00

###実現したいこと
下記の$arrから、actionに応じて配列を追加したいのですが、なかなか目的の位置に追加できません。

php

1$arr = array( 2 array( 3 'action' => 'get', 4 'target_id' => 10, 5 'actor_id' => [87], 6 ), 7 array( 8 'action' => 'lose', 9 'target_id' => 6, 10 'actor_id' => [87,37], 11 ), 12);

ゴールは上の$arrを下記「目的の配列」に変更することで、変更点としてはAとBの2つです。

A:actiongetの場合だけ、target_idに応じて、target_urltarget_ttlを追加する。(これはできました。)

B:どの場合でも、actor_idに応じて、actor_nameactor_imgを追加する。(これができません。)

###目的の配列

php

1array ( 2 0 => 3 array ( 4 'action' => 'get', 5 'target_id' => 10, 6 'target_url' => 'url of 10', // getなので追加(できた) 7 'target_ttl' => 'title of 10', // getなので追加(できた) 8 'actor_id' => 9 array ( 10 0 => 87, 11 ), 12 'actor_name' => 13 array ( 14 0 => 'name of 87', // 常に追加(できない) 15 ), 16 'actor_img' => 17 array ( 18 0 => 'img of 87', // 常に追加(できない) 19 ), 20 21 ), 22 1 => 23 array ( 24 'action' => 'lose', 25 'target_id' => 6, 26 'actor_id' => 27 array ( 28 0 => 87, 29 1 => 37, 30 ), 31 'actor_name' => 32 array ( 33 0 => 'name of 87', // 常に追加(できない) 34 1 => 'name of 37', // 常に追加(できない) 35 ), 36 'actor_img' => 37 array ( 38 0 => 'img of 87', // 常に追加(できない) 39 1 => 'img of 37', // 常に追加(できない) 40 ), 41 ), 42)

###試したこと
下記のような関数を書いてみました。

でも、Aの追加はできたのですが、Bの追加について「目的の配列」のようになりません。あれこれ切った貼ったしてみても直せず、よろしければご協力いただけませんでしょうか。

php

1// 追加のための関数 2function get_target_data($arr){ 3 $new=[]; 4 foreach ( $arr as $a ){ 5 // getの場合だけ追加(できた) 6 if( $a['action']=='get' ){ 7 $target_url = get_url( $a['target_id'] ); 8 $target_ttl = get_ttl( $a['target_id'] ); 9 $a += array( 'target_url' => $target_url ); 10 $a += array( 'target_ttl' => $target_ttl ); 11 } 12 $new[]=$a; 13 } 14 foreach ( $arr as $a ){ 15 // 常に追加(できない) 16 foreach ( $a['actor_id'] as $actor_id ){ 17 $actor_name = get_name( $actor_id ); 18 $actor_img = get_img( $actor_id ); 19 $a['actor_id'] += array( 'actor_name' => $actor_name ); 20 $a['actor_id'] += array( 'actor_avt' => $actor_img ); 21 } 22 $new[]=$a['actor_id']; 23 } 24 return $new; 25} 26 27// 追加する値 28function get_url($v){ 29 return 'url of '.$v; 30} 31function get_ttl($v){ 32 return 'title of '.$v; 33} 34function get_name($v){ 35 return 'name of '.$v; 36} 37function get_img($v){ 38 return 'img of '.$v; 39} 40 41// 確認 42$result = get_target_data($arr); 43var_export($result); 44

このコードの見た目で素人っぽさが判断できると思いますので、僭越ながらできれば上記の素人っぽい流れに近い形でご教授いただけますとうれしく思います。

よろしくお願い致します。

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

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

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

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

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

guest

回答1

0

ベストアンサー

こんなかんじです

PHP

1function get_url($v){ 2 return 'url of '.$v; 3} 4function get_ttl($v){ 5 return 'title of '.$v; 6} 7function get_name($v){ 8 return 'name of '.$v; 9} 10function get_img($v){ 11 return 'img of '.$v; 12} 13 14$arr = [ 15 [ 16 'action' => 'get', 17 'target_id' => 10, 18 'actor_id' => [87], 19 ], 20 [ 21 'action' => 'lose', 22 'target_id' => 6, 23 'actor_id' => [87,37], 24 ], 25 ]; 26$arr=array_map(function($x){ 27 if($x["action"]=="get"){ 28 $x["target_url"]=get_url($x["target_id"]); 29 $x["target_ttl"]=get_ttl($x["target_id"]); 30 } 31 $x["actor_name"]=array_map(function($x){ 32 return get_name($x); 33 },$x["actor_id"]); 34 $x["actor_img"]=array_map(function($x){ 35 return get_img($x); 36 },$x["actor_id"]); 37 return $x; 38},$arr); 39 40print_r($arr); 41

投稿2019/05/22 11:27

yambejp

総合スコア114572

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

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

love_kinniky

2019/05/22 11:58

array_map が入れ子になっておられる… ありがとうございます。少し難しかったですが、試しているうちにつかめてきました。たいへん勉強になりました。
love_kinniky

2019/05/22 14:06 編集

どうしても読み解けないところがあります。もしよかったら教えてください。 入れ子の array_map の、3つのうち後半の2つについてです。 この2つの ($x) は、 actor_id が書いてないのに、なぜ actor_id が代入されるのでしょうか? get_name($x); get_img($x); 下記のように actor_id を書かないといけないような感じがするんです。 get_name($x["actor_id"]); get_img($x["actor_id"]); なぜなら、3つのうちの最初の1つでは get_url($x["target_id"]); get_url($x["target_id"]); という風にして、target_id を指定してるじゃないですか? なのになぜ、後半の2つではその指定が不要になり、 actor_id を書かなくても、 actor_id が代入されるのでしょうか?
mepon

2019/05/22 13:51

横からすみません。 array_mapのマニュアルはこちら。 https://www.php.net/manual/ja/function.array-map.php array_mapは2個目のパラメータを使って1個目のコールバック関数を処理します。 一番最初は2個目のパラメータが$arrなので配列です。=keyを指定してあげる必要がある。 しかし、2,3回目は2個目のパラメータに },$x["actor_id"]); このような表記があります。この値がコールバック関数(今回は無名関数)の引数として渡されるので$xに代入されるため $xだけで良いということなんですよね
love_kinniky

2019/05/22 14:12 編集

mepon様、ありがとうございます。仰ること、わかったような気がします。ということは、後半の2つは下記のようにして「$x」の部分を、「$y」や「$z」にしても問題ないということでしょうか? $arr=array_map(function($x){ // 省略 $x["actor_name"]=array_map(function($y){ // $yにした return get_name($y); // $yにした },$x["actor_id"]); $x["actor_img"]=array_map(function($z){ // $zにした  return get_img($z); // $zにした },$x["actor_id"]); return $x; },$arr);
mepon

2019/05/22 14:20

はい、仰る通りで問題ありませんよ あくまで渡ってきた値を関数内ではこれとして扱いますといういわば宣言みたいなものなので(厳密にはちょっと違いますが) そこはyだろうがxだろうがhogeだろうが動作します
love_kinniky

2019/05/22 14:31

mepon様、ご返信ありがとうございます。なるほど関数内での関係なんですね。また機会がありましたら宜しくお願い致します。夜分にありがとうございました。 yambejp様へも重ねてお礼申し上げます。こんなわけて疑問は無事解決いたしました。
guest

あなたの回答

tips

太字

斜体

打ち消し線

見出し

引用テキストの挿入

コードの挿入

リンクの挿入

リストの挿入

番号リストの挿入

表の挿入

水平線の挿入

プレビュー

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

ただいまの回答率
85.50%

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

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

質問する

関連した質問