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

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

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

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

Q&A

解決済

4回答

3652閲覧

連想配列から特定のキーの値を取りだし、なおかつnullは除外する方法【PHP】

退会済みユーザー

退会済みユーザー

総合スコア0

PHP

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

0グッド

0クリップ

投稿2018/07/18 07:56

編集2018/07/18 08:31

フロント側で使う外部APIのラッパーを作っていた時に、こんなレスポンスに遭遇しました。

php

1$outsideResponse = [ 2 'id' => 2, 3 'tag1' => 'ハイブリット', 4 'tag2' => '新車', 5 'tag3' => null, 6]; 7 8※idは無視してください。tag以外にもデータが入ってることをわかりやすくするために入れてます。

仕様書によればタグは3つ固定で、設定されてなければnullが入るんだとか。これをそのままフロント側に渡すのは流石に扱いづらいと思ったので、nullを除くすべてをまとめることにしました。

php

1$tags = [ 2  'ハイブリット', 3  '新車', 4]

とりあえず変数にまとめるとすればこんな感じです。しかし僕はここで$outsideResponseから$tagsの状態にするコードをどう書くか迷ってしまいました。オーソドックスに書けば、

php

1$tags = null; 2if ($outsideResponse['tag1'] !== null) { 3 $tags[] = $outsideResponse['tag1']; 4} 5if ($outsideResponse['tag2'] !== null) { 6 $tags[] = $outsideResponse['tag2']; 7} 8if ($outsideResponse['tag3'] !== null) { 9 $tags[] = $outsideResponse['tag3']; 10}

こんな感じになると思います。しかし、いくら3つで固定されているからとはいえ、同じif文のコードを何度も書くのは僕にはちょっと違和感があります。できればこのコードをスマートにしたい。そこでこのコードをどう省略するか考えてみたのですが、どれもいまいちしっくりきません。

【foreachを使って省略】

php

1$key = [ 2  'tag1', 3  'tag2', 4  'tag3', 5]; 6$tags = null; 7foreach ($key as $value) { 8 if ($outsideResponse[$value] !== null) { 9 $tags[] = $outsideResponse[$value]; 10 } 11}

(しっくりこない点)
・$keyの配列数が増えれば増えるほど、結果的にコードが長くなる点(スマートになってない)。定数化して別ファイルにしてもいいですが、たがかnull判定でそこまでする?
・キーを配列化してforeachで回すという流れが、そもそも回りくどいように思えてきたから。

【三項演算子?で省略する】

php

1 2$tags = null; 3$outsideResponse['tag1'] !== null && $tags[] = $outsideResponse['tag1']; 4$outsideResponse['tag2'] !== null && $tags[] = $outsideResponse['tag2']; 5$outsideResponse['tag3'] !== null && $tags[] = $outsideResponse['tag3'];

(しっくりこない点)
・この書き方をしている人を見たことがない。この記事で知ったのですが、これは三項演算子なんでしょうか。それとも論理演算子?
・そもそも三項演算子があまり好きじゃない。1行に省略できるのは魅力的ですが、条件が複雑になれば複雑になるほど見づらくなるのがちょっと・・・。



このような感じで、結局なにも省略しないのが一番スマートなんじゃないかと思い始めてきたのですが、他の方の意見も聞いてみたいと思ってこのような質問をしてみました。もしよければ意見をお聞かせください。

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

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

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

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

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

m.ts10806

2018/07/18 08:08

なんとなく、タイトルが大枠過ぎて内容に寄れてない気がします。
guest

回答4

0

ベストアンサー

コメントついで

php

1$tags=array_filter($outsideResponse,function($val,$key){ 2 return substr($key,0,3)==='tag' && isset($val); 3},ARRAY_FILTER_USE_BOTH);

もしかして、tag_countみたいなカラムが
後から追加されるかもしれないという心配症で
コメントでは正規表現を提案しちゃったけど
まあ、とりあえずsubstrでいいよね

投稿2018/07/18 08:34

KazuhiroHatano

総合スコア7804

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

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

yambejp

2018/07/18 09:42

array_filterだけだと元のキーをひっぱっちゃうので、array_values してあげたほうがよいかもしれませんね
guest

0

こんなかんじですかね?

PHP

1$a = [ 2 'id' => 2, 3 'tag1' => 'ハイブリット', 4 'tag2' => '新車', 5 'tag3' => null, 6]; 7 8$b=[]; 9array_walk($a,function($x,$y) use(&$b){ 10 if(!is_null($x) and $y!=="id") $b[]=$x; 11}); 12 13print_r($b);

投稿2018/07/18 09:35

yambejp

総合スコア114777

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

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

0

  • 【foreachを使って省略】

tagが増えれば何もしないパターンだと3行増えるはずで、結果的に長くはならないと思います。
$keyなしでも、↓な感じではいかがでしょうか。

php

1foreach($outsideResponse as $key => $value) { 2 if(substr($key, 0, 3) !== 'tag') { continue; } 3 if($value === null) { break; } 4 $tags[] = $value; 5}
  • 【三項演算子?で省略する】

参照元に、「類似品」と書いてあるとおり、三項演算子とは言わないと思います。
&&は、false && somethingとなった時点で、somethingが何かにかかわらずfalseだからsomethingを評価しない、という性質を使って&&の左がtrueのときだけ、&&の右が評価(ここでは代入)が起こることになります。
個人的には、三項演算子は良いですが、三項演算子のネストはやめて欲しいですし、業務コードであまりトリッキーなことはしてほしくない(誰がメンテするか分からないので)と感じます。

投稿2018/07/18 08:23

papinianus

総合スコア12705

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

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

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

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

退会済みユーザー

退会済みユーザー

2018/07/18 08:09

$outsideResponseからtag1・tag2・tag3を抽出して、そこから空配列を削除するということでしょうか?
m.ts10806

2018/07/18 08:16

いえ。array_filter()をまず使ってみてください。 1次元であれば割と簡単にnull除外できるはずです。
KazuhiroHatano

2018/07/18 08:21

array_filterのcallbackでキー値も取るようにして キーが ^tag\d+$ かつ 値がnullでないならreturn true;ってことじゃないかな、
退会済みユーザー

退会済みユーザー

2018/07/18 08:28

なるほど。array_filterで配列をフィルタリングするということですね。たしかにそれは考えてなかったです。
guest

あなたの回答

tips

太字

斜体

打ち消し線

見出し

引用テキストの挿入

コードの挿入

リンクの挿入

リストの挿入

番号リストの挿入

表の挿入

水平線の挿入

プレビュー

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

ただいまの回答率
85.48%

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

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

質問する

関連した質問