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

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

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

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

Q&A

解決済

5回答

1861閲覧

配列のソートと結合

退会済みユーザー

退会済みユーザー

総合スコア0

PHP

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

0グッド

0クリップ

投稿2016/06/22 19:02

以下のような配列があります。

PHP

1{ 2"id": "250", 3"name": "hoge", 4"fee": "2000", 5"fee_plus": "2000" 6}, 7{ 8"id": "250", 9"name": "hoge", 10"fee": "3000", 11"fee_plus": "1200" 12}, 13{ 14"id": "250", 15"name": "hoge", 16"fee": "2800", 17"fee_plus": "2500" 18}, 19{ 20"id": "251", 21"name": "hoge256", 22"fee": "3800", 23"fee_plus": "3000" 24}, 25{ 26"id": "251", 27"name": "hoge256", 28"fee": "2900", 29"fee_plus": "4000" 30}, 31{ 32"id": "251", 33"name": "hoge256", 34"fee": "2500", 35"fee_plus": "4200" 36}

上記の配列から、「id」を毎に「fee」の値の中で一番最小値、「fee_plus」の値の中で一番最小値を取ってきて、結果的に「id」のデータを1件にしたいです。

先に結果のイメージを書くと以下です。

PHP

1{ 2"id": "250", 3"name": "hoge", 4"fee": "2000", 5"fee_plus": "1200" 6}, 7{ 8"id": "251", 9"name": "hoge256", 10"fee": "2500", 11"fee_plus": "4200" 12},

まずは、「fee」の中で最小値を取ろうと、以下のようにしてみました。

PHP

1foreach($arr as $key => $value) { 2 foreach ($value as $key2 => $value2) { 3 if ($key2 == 'fee') { 4 $hoge[] = $value2; 5 } 6 } 7} 8echo min($hoge);

このように最小値を取って、「id」毎にマージして、この最小値を各キーの値に入れ替えるようすれば、、、と考えたのですが、この時点(上記の記述)で各id毎にというのが崩れてしまいました・・・

こういった複雑な場合の処理はどのように行うのがよいのでしょうか?

ご教授のほどよろしくお願いいたします。

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

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

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

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

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

guest

回答5

0

(usort,"cmp") で、比較するキー名を
添字に指定して、
値をならべかえる。
これだと簡単です。

投稿2016/06/22 23:19

YK1037

総合スコア236

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

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

YK1037

2016/06/22 23:56

すいません。 usort(並び替えたい配列,"cmp") です。
退会済みユーザー

退会済みユーザー

2016/06/23 05:15

ご回答ありがとうございます。 一度feeの値が低い順に並び替えてから、考えると特定しやすいのですね! ソート系の関数をほかにも見つけたのでやってみます!
guest

0

ベストアンサー

ソースを書いてもあれなので、ぱっと思いつく流れを書いてみます。

1.現在の配列をID毎の単純配列に組みなおす。

PHP

1//こんなイメージ 2$arr = array( 3 "250" => array(array(要素1),array(要素2)), 4 "251" => array(上記と同様) 5);

2.それぞれのID事の配列をfeeをキーにしてarray_multisort()かforeachでソートする
3.ソート順に合わせてarray_pop()やarray_shift()で取得する

投稿2016/06/22 19:21

tanat

総合スコア18709

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

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

退会済みユーザー

退会済みユーザー

2016/06/23 05:12

ご回答ありがとうございます。 ID毎に多次元配列を一次元配列に組み直して、foreachで回して各配列のfeeとfee_plusで最小値をソートして組み直すことができました。 考え方を教えてくださり、ありがとうございました!
tanat

2016/06/23 05:21

上手くいったようで何よりです。 差し支えなければ出来上がったソースを質問に追記していただけると、 今後、同じような質問があった場合に参考になるかと思います。
guest

0

id=251のfee_plusの最小値は3000じゃないの?
idを取っておくテンポラリ配列をもつと楽

<?PHP $myarray=array( array("id"=>"250","name"=>"hoge","fee"=>"2000","fee_plus"=>"2000"), array("id"=>"250","name"=>"hoge","fee"=>"3000","fee_plus"=>"1200"), array("id"=>"250","name"=>"hoge","fee"=>"2800","fee_plus"=>"2500"), array("id"=>"251","name"=>"hoge256","fee"=>"3800","fee_plus"=>"3000"), array("id"=>"251","name"=>"hoge256","fee"=>"2900","fee_plus"=>"4000"), array("id"=>"251","name"=>"hoge256","fee"=>"2500","fee_plus"=>"4200"), ); $minarray=array(); $tmparray=array(); foreach($myarray as $vals){ if(!array_key_exists($vals["id"],$tmparray)) $tmparray[$vals["id"]]=count($tmparray); if(!array_key_exists($tmparray[$vals["id"]],$minarray)) $minarray[$tmparray[$vals["id"]]]=$vals; if($vals["fee"]<$minarray[$tmparray[$vals["id"]]]["fee"]) $minarray[$tmparray[$vals["id"]]]["fee"]=$vals["fee"]; if($vals["fee_plus"]<$minarray[$tmparray[$vals["id"]]]["fee_plus"]) $minarray[$tmparray[$vals["id"]]]["fee_plus"]=$vals["fee_plus"]; } unset($tmparray); print_R($minarray);

投稿2016/06/23 00:58

yambejp

総合スコア114583

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

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

退会済みユーザー

退会済みユーザー

2016/06/23 05:19

ご回答ありがとうございます。 実際に試したところ無事に動作しました! array_key_existsでid毎にしぼってその後に比較しているんでしょうか。 理解不足なので1つずつ関数調べてどうなってるか考えてみます! ありがとうございました!
guest

0

質問者様のコードを踏襲した場合。

PHP

1// idをキーにした連想配列にまとめる 2foreach($arr as $key => $value) { 3 $temp[$value['id']]['name'] = $value['name']; 4 $temp[$value['id']]['fee'][] = $value['fee']; 5 $temp[$value['id']]['fee_plus'][] = $value['fee_plus']; 6} 7// 最小値を求めながら$hogeに詰め直す 8foreach($temp as $key => $value) { 9 $hoge[count($hoge)-1]['name'] = $value['name']; 10 $hoge[count($hoge)-1]['fee'] = min($value['fee']); 11 $hoge[count($hoge)-1]['fee_plus'] = min($value['fee_plus']); 12}

あまりスマートではないですね・・・。

投稿2016/06/23 00:33

ttyp03

総合スコア16996

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

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

退会済みユーザー

退会済みユーザー

2016/06/23 05:16

ご回答ありがとうございます。 コード理解できました! min()という関数で最小値を取得して配列を組み直すということですね! 多次元配列でも一度配列を組み直すといろいろ見えてきそうです!
guest

0

オーソドックスなやり方は次のようなものではないでしょうか?

  1. 連想配列 A を用意します。
  2. データを走査し、走査中のデータの id をキーとするものが A に無いならば作成し、fee の値を入れます。あるならば、既存のものよりも走査中の fee の方が小さい場合だけ入れます。

投稿2016/06/22 22:44

Zuishin

総合スコア28656

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

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

退会済みユーザー

退会済みユーザー

2016/06/23 05:14

ご回答ありがとうございます。 一度feeやfee_plusの値だけ、連想配列に入れて比較するということでしょうか? 実装は出来ましたが、いろんなパターンでやってみたいと思います!
guest

あなたの回答

tips

太字

斜体

打ち消し線

見出し

引用テキストの挿入

コードの挿入

リンクの挿入

リストの挿入

番号リストの挿入

表の挿入

水平線の挿入

プレビュー

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

ただいまの回答率
85.50%

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

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

質問する

関連した質問