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

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

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

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

Q&A

解決済

2回答

1056閲覧

PHPで、同じ値がない場合のみ、配列を連結させたい

love_kinniky

総合スコア22

PHP

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

0グッド

0クリップ

投稿2019/03/04 02:38

編集2019/03/04 05:28

###実現したいこと

後述するソースコードで
「新しい配列 $new」を「現在の配列 $current」の上に連結させたいです。

しかし連結させる条件(同じactionがない場合のみ)が複雑で、歯が立ちません。

先にソースコードの実行サンプルがありますのでよろしけれはご覧ください。
http://codepad.org/5hJVItQb

###躓いている部分
それぞれの処理にコメントと番号がありますが、その2番目の、

//【処理2】同じactionがなければ、年月日の配列を連結して終了ができない状況です。

この4行を削除したとき(つまり $new の action が $current の action と同じであるとき)は、問題なく作動致します。

同じ action がない場合の連結を実現したいです。

以下、それぞれの配列と、配列連結のために書かれたソースコードになります。

###新しい配列
こちらが新しく連結される配列 $new になります。

PHP

1/* 2* 新しい配列 $new 3*/ 4$new = array( 5 '2019-01-02'=> array( 6 array( 7 'action'=>'banana', 8 'time'=>'01-02', 9 'targetID'=>'1', 10 'actorID'=>'17', 11 'subID'=>'77', 12 ) 13 ) 14);

###現在の配列
こちらはすでにある配列 $current です。この 2019-01-02 の先頭に banana を連結させたい感じです。

PHP

1/* 2* 現在の配列 $current 3*/ 4$current = array( 5 '2019-01-02'=> array( 6 array( 7 'action'=>'orange', 8 'time'=>array('01-02','01-01'), 9 'targetID'=>'200', 10 'actorID'=>array('16','15'), 11 'subID'=>array('6','22'), 12 ), 13 array( 14 'action'=>'apple', 15 'time'=>array('01-02','01-01'), 16 'targetID'=>'1', 17 'actorID'=>array('14','13'), 18 'subID'=>array('86','64'), 19 ), 20 ), 21 '2019-01-01'=> array( 22 array( 23 'action'=>'apple', 24 'time'=>array('01-01','01-01'), 25 'targetID'=>'1', 26 'actorID'=>array('4','3'), 27 'subID'=>array('1','33'), 28 ), 29 ), 30);

###該当のソースコード
こちらが連結のためのソースコードです。
//【処理2】同じactionがなければ、年月日の配列を連結して終了がおかしいようですが、どのようにすべきでしょうか?

PHP

1foreach($new as $day => $contents) { 2 foreach($contents as $content) { 3 //【処理1】同じ年月日がなければ、年月日の配列を連結して終了 4 if(!isset($current[$day])) { 5 $current = array_merge($new, $current); 6 continue; 7 } 8 //【処理2】同じactionがなければ、年月日の配列を連結して終了 9 if($current[$day]['action'] !== $content['action']) { 10 $current = array_merge($new, $current); 11 continue; 12 } 13 //【処理3】同じ年月日で同じactionがあれば、年月日の配列の中の3つの配列を連結して、新しい20個だけをとっておく 14 for($i = 0; $i < count($current[$day]); $i++) { 15 $current[$day][$i]['time'] = array_slice(array_merge([$content['time']], $current[$day][$i]['time']), 0, 20); 16 $current[$day][$i]['actorID'] = array_slice(array_merge([$content['actorID']], $current[$day][$i]['actorID']), 0, 20); 17 $current[$day][$i]['subID'] = array_slice(array_merge([$content['subID']], $current[$day][$i]['subID']), 0, 20); 18 } 19 //新しいのを上に 20 $sortkey = array_map(function($ar) { return $ar[0];}, array_column($current[$day], 'time')); 21 array_multisort($sortkey, SORT_DESC,$current[$day]); 22 } 23} 24var_export($current);

長くなってしまって申し訳ございません。お気づきの点があればなんでも仰ってください。

どうぞ宜しくお願い致します。

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

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

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

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

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

m.ts10806

2019/03/04 03:26

そもそもNotice出てるのでこちら修正が先決では
yambejp

2019/03/04 03:35

すでにある場合はどうするのでしょう? 無視するのか上書きするのか
love_kinniky

2019/03/04 03:37

mts10806さま、すみません、エラーの順番というのはどのように考えるべきでしょうか。
love_kinniky

2019/03/04 03:42

yambejpさま、「すでにある場合」とは、「$newと同じ年月日が$currentにある場合」もしくは「$newと同じactionが$currentにある場合」ですよね。いずれの場合も該当のソースコードの【処理3】になると思って頂ければと思います。
m.ts10806

2019/03/04 03:50

>エラーの順番というのはどのように考えるべきでしょうか。 ??? エラーが出ているコードを提示されてもそこを修正するところからになるので 本題にすぐに入れるわけではないという話なのですが
love_kinniky

2019/03/04 05:15 編集

mts10806さま、なるほどそうでしたか。今回の質問はそちらのエラーが本題です。他の連結は問題ありません。 たとえばエラー部分(【処理2】の4行)を削除すると、$new の action が $current の action と同じである限り( apple もしくは orange である限り)、問題なく作動しますよね。 今回はこの action が違うケース( banana であるケース)が上手くいかず、それが質問のエラー箇所になります。 難しいですよね。
papinianus

2019/03/04 05:04

paizaのプロジェクトがyambejp様回答になってるのは、そちら本命で行くってことでよろしいか?
love_kinniky

2019/03/04 05:12

papinianusさま、paizaのプロジェクトは上書きされてしまったのだと思います。上書きを避けるためにcodepadにしておきました。 質問にあるソースコードはかなり時間をかけ苦労して読解した部分もあるので、今回はyambejpさまのご回答に沿った形というよりも、質問にあるコードに沿ったような形でご回答頂けますと、個人的には大変助かります…。
m.ts10806

2019/03/04 05:14

なるほどそれならそこは書いておいてもらいたいところですね。 本題であれば「何が問題か」を認識してるかどうかは書かれないとわかりませんので。 追記願います。
love_kinniky

2019/03/04 05:28 編集

mts10806さま、たしかに、仰る通りかと!わかりにくい文面で大変失礼いたしました。問題点を書いておきました。ご指摘ありがとうございます。
guest

回答2

0

ベストアンサー

57行付近のブロックしか見てません。
($newがappleの場合を見てません)

javascript

1 //同じactionがなければ、年月日の配列を連結して終了 2 if(!in_array($content['action'], array_column($current[$day], 'action'), true)) { 3// $current = array_merge_recursive($current,$new); 4 $current = array_merge_recursive($new, $current); 5 continue; 6 }

投稿2019/03/04 03:40

編集2019/03/04 05:06
papinianus

総合スコア12705

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

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

love_kinniky

2019/03/04 03:49

papinianusさま、いつもお世話になっております。今回もすばやいご回答をありがとうございます。bananaが追加されました。 ただ、すみません、追加されたbananaですが、'2019-01-02' の 0個目に来てほしいです…すみません!!!! $newの追加位置は同年月日の先頭で、もし同日がなければ全体の先頭にきてほしいというイメージです。 $newがappleの場合は問題なさそうです。ありがとうございます。
papinianus

2019/03/04 05:07

> ただ、すみません、追加されたbananaですが、'2019-01-02' の 0個目に来てほしいです…すみません!!!! マージ的に、マージする本体に、部分を足す、ていう順序にしただけで、順序性が大事なら、array_merge_recursiveの引数の順序を逆にすればいいと思います。 回答を修正しました。
love_kinniky

2019/03/04 05:30

できました!! array_merge系は、引数の順番を変えれば連結も可変なんですね。(あたりまえか笑)考えてませんでした。 いつも本当にありがとうございます。今回の質問でばっちり想定のものができました。けっきょく私の配列の機能は、全てpapinianusさまに作って頂くことになってしまいました…。(*_ _)人アリガトウゴザイマス
guest

0

ごめんなさい、いまいち理解できない部分があるのでとりあえず勝手に解釈

PHP

1$new = [ 2 '2019-01-02'=> [ 3 [ 4 'action'=>'banana', 5 'time'=>'01-02', 6 'targetID'=>'1', 7 'actorID'=>'17', 8 'subID'=>'77', 9 ], 10 ], 11 ]; 12$current = [ 13 '2019-01-02'=> [ 14 [ 15 'action'=>'orange', 16 'time'=>['01-02','01-01'], 17 'targetID'=>'200', 18 'actorID'=>['16','15'], 19 'subID'=>['6','22'], 20 ], 21 [ 22 'action'=>'apple', 23 'time'=>['01-02','01-01'], 24 'targetID'=>'1', 25 'actorID'=>['14','13'], 26 'subID'=>['86','64'], 27 ], 28 ], 29 '2019-01-01'=> [ 30 [ 31 'action'=>'apple', 32 'time'=>['01-01','01-01'], 33 'targetID'=>'1', 34 'actorID'=>['4','3'], 35 'subID'=>[!'1','33'], 36 ], 37 ], 38 ]; 39 40$key=array_keys($new)[0]; 41$action=$new[$key][0]["action"]; 42if(count(array_filter($current[$key],function($x) use($action){ 43 return $x["action"]==$action; 44}))==0){ 45 $current[$key][]=$new[$key][0]; 46} 47print_r($current); 48 49

投稿2019/03/04 03:49

yambejp

総合スコア114572

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

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

love_kinniky

2019/03/04 04:09

ありがとうございます。 まず banana は連結されましたが、これは 2019-01-02 の 0個目に来てほしかったです。(質問に書いておらず失礼致しました。) 何より、「 $new が banana でなく apple の場合」に、連結が起こらないみたいです。 「 $new が banana でなく apple の場合」というのは、「同じ年月日で同じ action がある」ということになります。なので、【処理3】にあるような連結を考えています。(質問のソースコードではこの処理はできていると思います。) 複雑ですみません。
guest

あなたの回答

tips

太字

斜体

打ち消し線

見出し

引用テキストの挿入

コードの挿入

リンクの挿入

リストの挿入

番号リストの挿入

表の挿入

水平線の挿入

プレビュー

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

ただいまの回答率
85.50%

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

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

質問する

関連した質問