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

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

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

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

Q&A

解決済

2回答

1183閲覧

PHP多次元連想配列で、あるキーの値が等しいとき、別キーの値を統合したい。

jonsmith

総合スコア5

PHP

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

0グッド

0クリップ

投稿2020/03/25 00:16

編集2020/03/25 00:23

前提・実現したいこと

$sourceのidが同じとき、preを統合させて、$targetを作りたいです。

php

1$source = array( 2 array('id'=>1, 'pre'=>'東京', 'rank'=>'A'), 3 array('id'=>1, 'pre'=>'大阪', 'rank'=>'A'), 4 array('id'=>4, 'pre'=>'沖縄', 'rank'=>'B'), 5);

↓統合させたい

php

1$target = array( 2 array('id'=>1, 'pre'=>['東京','大阪'], 'rank'=>'A'), 3 array('id'=>4, 'pre'=>['沖縄'], 'rank'=>'B'), 4);

発生している問題・エラーメッセージ

Uncaught Error: [] operator not supported for strings

該当のソースコード

実現することと近い以下のソースコードをネットから教えて頂きました。

以下のソースコードは
"東京,大阪"

となるのですが、その部分が
["東京","大阪"]

となれば実現したいことができます。

php

1$target = array(); 2foreach ($source as $item) { 3 $id = $item['id']; 4 foreach ($target as $skey=>$out) { 5 if ($out['id'] === $id) { 6 $outkey = $skey; 7 } 8 } 9 if (!isset($outkey)) { 10 $target[] = $item; 11 } else { 12 $target[$outkey]['pre'] .= ',' . $item['pre']; 13 unset($outkey); 14 } 15} 16print_r($target); 17 18

試したこと

実現したいことのために、こちらの部分を

$target[$outkey]['pre'] .= ',' . $item['pre'];

次のように変更しますと、先のエラーとなってしまうのです。

$target[$outkey]['pre'][] = $item['pre'];

エラーに対して試したこと

そこでエラーを見てますとstringsが悪いようで、こちらでstringsがそのまま追加されているのが悪いのかとあたりをつけまして、

php

1 if (!isset($outkey)) { 2 $target[] = $item; 3 }

次のように変更し、preなら配列として扱うようにしてみたのですがやはりできず、どうしてもわからないので質問させて頂きました。

php

1 if (!isset($outkey)) { 2 foreach ( $item as $k=>$v ) { 3 if( $k === 'pre' ){ 4 $target['pre'][] = $v; 5 }else{ 6 $target[$k] = $v; 7 } 8 } 9 }

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

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

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

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

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

guest

回答2

0

ベストアンサー

preが文字列だったり配列だったり型が混在するのは避けるべきです
またrankが異なるときどちらが優先されるかも不明です

投稿2020/03/25 00:21

yambejp

総合スコア116724

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

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

jonsmith

2020/03/25 00:25

申し訳ございません。型は配列でrankが異なることはないのでその2点を修正致しました。
yambejp

2020/03/25 01:03

idとrankは常に連動しているということですね。 $a = [ ['id'=>1, 'pre'=>'東京', 'rank'=>'A'], ['id'=>1, 'pre'=>'大阪', 'rank'=>'A'], ['id'=>4, 'pre'=>'沖縄', 'rank'=>'C'], ]; $b=[]; foreach($a as $val){ $c=&$b[$val["id"]]; if(!is_array($c["pre"])) $c["pre"]=[]; $c["id"]=$val["id"]; array_push($c["pre"],$val["pre"]); $c["rank"]=$val["rank"]; } $b=array_values($b); print_r($b);
jonsmith

2020/03/25 03:06

だいぶスッキリしました。ありがとうございます。 一つ補足で、$sourceが質問のように固定でない場合があります。たとえば以下の札幌のように「age」だったりということです。なので以下としてみました。「age」にも対応できるようにforeachで変数とした流れです。 <?php $a = [ ['id'=>1, 'pre'=>'東京', 'rank'=>'A'], ['id'=>1, 'pre'=>'大阪', 'rank'=>'A'], ['id'=>4, 'pre'=>'沖縄', 'rank'=>'C'], ['id'=>5, 'pre'=>'札幌', 'age'=>'20'] ]; $b=[]; foreach($a as $val){ $c=&$b[$val["id"]]; if(!is_array($c["pre"])) $c["pre"]=[]; foreach( $val as $k => $v ){ if ( $k == 'pre' ){ array_push($c["pre"],$val["pre"]); }else{ $c[$k]=$val[$k]; } } } $b=array_values($b);
jonsmith

2020/03/25 03:12 編集

そして、質問よろしいでしょうか。 上記をvar_dump($b)しますと、札幌がある配列($b[2]の配列)に「&」という記号が付きます。下記です。 array(3) { [0]=> array(3) { ["pre"]=> array(2) { [0]=> string(6) "東京" [1]=> string(6) "大阪" } ["id"]=> int(1) ["rank"]=> string(1) "A" } [1]=> array(3) { ["pre"]=> array(1) { [0]=> string(6) "沖縄" } ["id"]=> int(4) ["rank"]=> string(1) "C" } [2]=> &array(3) { ["pre"]=> array(1) { [0]=> string(6) "札幌" } ["id"]=> int(5) ["age"]=> string(2) "20" } } この「&」が何か…?もしご存じでしたら教えて頂けませんでしょうか? 見た感じ「$c=&$b[$val["id"]];」に関係していそうですが、この行の意味が解読できないために、札幌の配列に「&」が付く理由もわからないでおります。
yambejp

2020/03/25 03:19

なるほどキーが一律ではないのですね $a = [ ['id'=>1, 'pre'=>'東京', 'rank'=>'A'], ['id'=>1, 'pre'=>'大阪', 'rank'=>'A'], ['id'=>4, 'pre'=>'沖縄', 'rank'=>'C'], ['id'=>5, 'pre'=>'札幌', 'age'=>'20'] ]; $b=[]; foreach($a as $val){ $c=&$b[$val["id"]]; if(!is_array($c["pre"])){ $c=array_filter($val,function($x){return $x!=="pre";},ARRAY_FILTER_USE_KEY); $c["pre"]=[]; } array_push($c["pre"],$val["pre"]); } unset($c); $b=array_values($b); var_dump($b); 「&」マークが付くのは参照渡ししているからです unsetしてやってください。
jonsmith

2020/03/25 03:29

なんとご丁寧に…細やかにご対応頂き感謝致します。参照渡しは聞いたことしかありあませんでした。array_filterも使ったことがなく、大変噛み応えのあるコードで勉強になります。どうもありがとうございました。
guest

0

こんな感じにするしかないのでは?

php

1 if (!isset($outkey)) { 2 $target[] = ['id' => $item['id'], 'pre' => [$item['pre']], 'rank' => $item['rank']]; 3 } else { 4 $target[$outkey]['pre'][] = $item['pre']; 5 unset($outkey); 6 }

投稿2020/03/25 01:33

Y.H.

総合スコア7918

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

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

jonsmith

2020/03/25 02:57

なるほど1つずつ改めて入れなおすと。ありがとうございます。
Y.H.

2020/03/25 03:10

まとめて入れても結局どこかで$target[$outkey]['pre']をarray()にすげ替える為のifブロックが必要になるだけですし。
guest

あなたの回答

tips

太字

斜体

打ち消し線

見出し

引用テキストの挿入

コードの挿入

リンクの挿入

リストの挿入

番号リストの挿入

表の挿入

水平線の挿入

プレビュー

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

ただいまの回答率
85.35%

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

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

質問する

関連した質問