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

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

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

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

JavaScript

JavaScriptは、プログラミング言語のひとつです。ネットスケープコミュニケーションズで開発されました。 開発当初はLiveScriptと呼ばれていましたが、業務提携していたサン・マイクロシステムズが開発したJavaが脚光を浴びていたことから、JavaScriptと改名されました。 動きのあるWebページを作ることを目的に開発されたもので、主要なWebブラウザのほとんどに搭載されています。

Q&A

解決済

5回答

4847閲覧

≪ほかの言語もどうぞ≫ a = b? b: c; の冗長性を排除するには?

Takahashi-Ei

総合スコア60

PHP

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

JavaScript

JavaScriptは、プログラミング言語のひとつです。ネットスケープコミュニケーションズで開発されました。 開発当初はLiveScriptと呼ばれていましたが、業務提携していたサン・マイクロシステムズが開発したJavaが脚光を浴びていたことから、JavaScriptと改名されました。 動きのあるWebページを作ることを目的に開発されたもので、主要なWebブラウザのほとんどに搭載されています。

5グッド

13クリップ

投稿2016/03/09 13:22

編集2016/03/09 13:23

JSer、PHPerです。

初期値を整理するときなどに、

php

1// bが存在しないならcを初期値にする 2a = b? b: c;

というコードを使うと思うのですが、bが二回出てくるのを何とかして、スキっとさせることは可能でしょうか?

bが長ったらしい名前だったりすると結構悲惨です。

もしかすると基本かもしれませんが、よろしくお願いします。

また、Javascript、php以外の言語で、こんなのもあるよ、というのがあれば、そちらも参考のためにお願いします。

ao_love, takotakot, ucan-lab👍を押しています

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

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

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

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

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

guest

回答5

0

ベストアンサー

php

1$a = $b ?: $c;

javascript

1a = b || c

ruby

1a = b || c

python

1a = b or c

投稿2016/03/09 13:29

編集2016/03/09 13:30
ngyuki

総合スコア4514

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

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

Takahashi-Ei

2016/03/09 13:48

$a = $b ?: $c; ↑こんなのがあるんですね!知りませんでした… これでスッキリ書け、ぐっすり寝られます。 ありがとうございました!
miyabi-sun

2016/03/10 00:25

これはPHP7で出てきた書き方ですね。 PHP5.6以前は配列のキーが存在するか否かを確認する際は、 下記のように書く必要が有るためめんどくせーって言われてました。 $a = isset($b['hoge']) ? $b['hoge'] : $c; PHP7では上記の書き方が出来るようになり、こう! $a = $b['hoge'] ?: $c;
miyabi-sun

2016/03/10 02:40

あ、すみません、すっかり勘違いしてしまいました。
ef3

2016/03/10 23:48 編集

b = nil のケースの a は nil であるべき? 例えば Ruby なら a = defined?(b) ? b : c とすべきなのかも。 ```python a = b if 'b' in locals() or 'b' in globals() else c ```
ngyuki

2016/03/11 01:04

「変数が存在するかどうか」ならそうですね
ef3

2016/03/11 11:27

「初期値を整理するときなど」というテーゼで従った解です。
ef3

2016/03/11 11:41

質問の解釈に誤謬がある
guest

0

質問文にあるとおり,「変数が存在するかどうか」 の確認ならisset相当のチェックを行うべきですよね.

php

1$a = isset($b) ? $b : $c;

こんなときは,PHP7から実装されたコイツの出番です.

php

1$a = $b ?? $c;

PHP5では,$_GET $_POST $_COOKIE に対しては一応 filter_input という救済手段があります.
(PHP7でもfilter_varは普通に使うかも)

なお,PHP以外の他の言語においては,issetのようなエラー発生を回避するための仕組みが必要なことは稀です.

JavaScript (strictモード)

  • 変数が同じ関数スコープにおいて条件分岐や書かれた場所に関わらず var 宣言されている場合,
    代入されていなくても undefined としてエラー無しに参照できる
    (現在より下の行に書かれていてもOKになることは「巻き上げ」と呼ばれる)
  • 変数が同じブロックスコープ内の現在より上の行で let 宣言されている場合,
    代入されていなくても undefined としてエラー無しに参照できる
    (letではvarと違って巻き上げは起こらない)
  • プロパティが代入されていない場合,undefinedとしてエラー無しに参照できる

上記に該当しない場合は Reference Error が発生します.
JavaScriptには変数が参照可能かどうかをエラーの発生なしに確認する手段はありません.
(グローバル変数を除く)

Ruby

  • 変数が同じ関数スコープにおいて条件分岐に関わらず現在より上の行で代入する記述がある場合,
    代入されていなくても nil としてエラー無しに参照できる
    (RubyではJavaScriptのvarのように巻き上げは起こらない)

上記に該当しない場合は Name Error が発生します.
Rubyでは変数が参照可能かどうかを defined? で確認出来ます.
(PHPのissetのように頻繁に使われることはありません)

Pythonはちょっとわかりません,すいません

投稿2016/03/09 13:50

編集2016/03/09 19:32
mpyw

総合スコア5223

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

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

Takahashi-Ei

2016/03/09 13:55

ちょっと調べてみましたが、$bがnullでもエラーが出ないんですね。 これは助かります。重宝しそうです! ありがとうございました!
mpyw

2016/03/09 14:10

回答に補足を追記しました.
think49

2016/03/09 14:43 編集

> JavaScript (strictモード) > - 変数が同じブロックスコープにおいて let 宣言されている場合, 代入されていなくても undefined としてエラー無しに参照できる ReferenceError になる仕様だったと思います(Google Chrome 49.0.2623.87 m で再現しました)が、そうではない実装があるのでしょうか。 https://jsbin.com/gubaforopa/edit?html,output
kagi_shippo

2016/03/09 15:59 編集

CertaiNさん先ほどは補足ありがとうございます。 > ・変数が同じ関数スコープにおいて条件分岐に関わらず var 宣言されている場合,代入されていなくても undefined としてエラー無しに参照できる 素敵。 そこでJavaScriptでは、それを undefined 判定に利用してスッキリ。 var undef, a, b = null; console.log(a === undef, b === undef);
mpyw

2016/03/09 19:01

think49さん,ご指摘ありがとうございます.私が想定していたのはあらかじめ let a; console.log(a); のように頭で宣言しておく場合で,これが逆転する「巻き上げ」については意識してませんでした.せっかく var についても触れているので,さらに編集しておきます.
mpyw

2016/03/09 19:23 編集

kagi_shippoさん undefined判定ですが,最近のJavaScriptの仕様(ES5以降)では,グローバルなundefinedという変数は上書き不可になっており,これをそのまま使ってしまって構いません.関数スコープにおいて var undefined = 1; console.log(undefined); とした場合は 1 になってしまいますが,これはそういう変数名を作るほうが悪いということで…w 巻き上げは結構気持ち悪くて,「書かれた場所に関わらず」と書いたとおり var a = 1; (function () { console.log(a); var a = 2; })(); これ undefined になっちゃいますし,「条件分岐に関わらず」と書いたとおり var a = 1; (function () { if (false) { var a = 2; } console.log(a); })(); こっちもundefinedになっちゃいます.
kagi_shippo

2016/03/10 00:26 編集

CertaiNさん そこで function something() {   var undef, a, b = null;   console.log(a === undef, b === undef); } です。 undefined を使って undefined判定を行うと指摘されたような懸念があるので、undefined判定を行いたいブロック内で、var undef; などと自分で 「undefined としてエラー無しに参照できる変数」(素敵) を宣言します。(同じブロック内で何か代入しない限り、undefは、undefined値。) 何も代入しないブロックスコープの変数(undef等)を var宣言しておくと、undefined判定がスッキリ書けて便利です。
mpyw

2016/03/10 04:56

あ,変数名が短いことによる恩恵という意味ですね(納得
kagi_shippo

2016/03/10 07:11 編集

というより、ステートメントが短いことによる恩恵ですね var undef; typeof a === 'undefined' 本来 a === undefined     どこかでundefinedに何か代入されていると× a === undef       typeof を使わないぶん短い
think49

2016/03/10 23:06 編集

> a === undefined     どこかでundefinedに何か代入されていると× > a === undef       typeof を使わないぶん短い undef も別の値が代入されるとNGなので書き換えたい策としては undefined よりも状況は悪くなっているような…。 undefined のローカル変数化は ES3 の頃に存在したテクニックですが、ES5 のグローバル変数 undefined と違ってローカル変数は書き換え可能です。 スコープチェーン上の書き換えを懸念するならば typeof 演算子か void 演算子を活用するのがベターだと思います。
guest

0

明示しない限り、原則ショートサーキット(1番目を返す場合は、2番目は評価されない)です。

"0"の扱いがPerl 5とPrel 6で異なります。

Perl

1# $b が 偽 なら 2# Perl 5 では 0, "0", "", (), undef の五つのみ 3# "0" が Perl 5 では偽になるが、Perl 6 では真になる。 4# Perl 6 では Bool 型への変換で False になるオブジェクト 5# False, 0, "", [], {}, Any, Nil, etc.. 6# 任意の型で何が偽であるかを定義できるため、無数に存在し得る。 7$a = $b || $c; 8# $b が 未定義なら 9# defined($b) が偽かどうかで判断する。 10# Perl 5 では undef かどうかになる。 11# Perl 6 では Any や Int などになり、Mu や Nil 等も未定義の一つに含まれる。 12# Perl 5 + use strict や Perl の場合、未宣言はエラーになる。 13$a = $b // $c;

未定義かどうかを判断することはできないようです。

Python

1# b が 偽 なら 2# __bool__() が False になるオブジェクト 3# False, 0, "", (), [], {}, None, etc... 4# 任意の型で何が偽であるかを定義できるため、無数に存在し得る。 5# 未定義はエラーになる。 6a = b or c

PHP 7から??が追加されました。

PHP

1// $b が 偽 なら 2// boolean への変換で FALSE になるオブジェクト 3// 0, 0.0, "", "0", [], NULL, 空のSimpleXMLElement 4$a = $b ?: $c; 5// $b が 未定義 なら 6// PHP 7 からの機能 7// 未定義な変数は NULL であり、NULL かどうかの判断になる。 8$a = $b ?? $c;

変数の種類によって未定義の変数がどうなるかが異なります。

Ruby

1# b が 偽 なら 2# 偽は nil, false の二つのみ 3# グローバル変数、インスタンス変数、クラス変数が未定義の場合、 4# nil が定義されたものと見なされるため、未定義の場合という条件に使用できる。 5# ローカル変数や定数が未定義の場合は、エラーになる。 6a = b || c 7# しかし、||= の場合は、前段階の処理で定義済みとされるため、エラーにならない。 8a || = b 9# 上は下の糖衣構文 10a = a || b 11# 処理として、a が未定義の場合、始めに a が定義されたものと見なされ、 12# a には nil が入っているとし、偽であるから、b が a に代入される。

NaNも偽になります。

JavaScript

1// b が 偽 なら 2// 偽は undefined, null, false, +0, -0, NaN, '' 3// 未定義は undefined が入るが、未宣言はエラーになる。 4a = b || c;

JavaScriptと違って未定義(未宣言)の場合も簡単に確認できるようになります。

CoffeeScript

1# b が 偽 なら 2# JavaScript の || と同じになるし、|| と書くこともできる。 3a = b or c 4# b が 未定義 または null または undefined なら 5# typeof を使用するため、エラーにならずに未定義か判断できる。 6a = b ? c

int?などNullable型にすればプリミティブ型にも使えます。

C#

1// Nullable型: b が null なら 2a = b ?? c;

関数型言語はMabye型のようなものであれば、同じようにできます。<|>は構文ではなく、中置演算子という関数の一種ですが、Haskellは遅延評価であるため、ショートサーキットになります。

Haskell

1--- Maybe: bNothing なら 2a = b <|> c

もうひとつ関数型の例。Noneはnullとは異なる概念です。構文ではなく関数で構成されており、Scalaは正格評価であるため、ショートサーキットではありません

Scala

1// b が null なら 2a = Option(b).getOrElse(c); 3// Option型: b が None なら 4a = b.orElse(c)

Java 8にはOptionalというのがあるらしいです。構文ではなく関数で構成されており、Javaは正格評価であるため、ショートサーキットではありません

Java

1// b が null なら ※ Java 8 から 2a = java.util.Optinoal.ofNullable(b).orElse(c);

投稿2016/03/09 14:34

編集2016/03/11 15:25
raccy

総合スコア21735

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

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

0

JavaScript なら || を使う方法がありますね。

JavaScript

1var a = b || c;

Re: Takahashi-Ei さん

投稿2016/03/09 13:26

think49

総合スコア18162

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

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

Takahashi-Ei

2016/03/09 13:49

PHPの場合と違う結果になるんですね! 勉強になりました。ありがとうございます!
mpyw

2016/03/09 13:51

PHPの || は強制的に論理値にしちゃう残念実装です…w
guest

0

縮めてスッキリさせる方法が出尽くした感じなので、あえて便乗させてください。

逆説的ですが
やはり初期値を整理するときなどに、判定しまくりなら三項演算子をつなぎまくると、逆にスッキリって場合もありです。

a = b > 100 ? c : b > 10 ? d : b > 1 ? e : b ? f : a;

インデント頼りで芸がないですが、ifや、Switchより見やすく短いんで。

投稿2016/03/09 14:24

編集2016/03/09 14:29
kagi_shippo

総合スコア105

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

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

Takahashi-Ei

2016/03/09 14:31

はーー、こんな方法があったんですね! いやほんと、ifや、Switchより見やすく短いです。 機会があったらぜひ使ってみます。ありがとうございます!
kagi_shippo

2016/03/10 00:16 編集

あーー! 最大級にありがとうございます!!!! 人のスレに便乗しておきながら、ほんとすんません! php無知でした つまりphpでそのまんまやろうとすると、こういうキモいことになるわけですね・・・ $a = $b > 100  ? $c  :(    $b > 10   ? $d  :(    $b > 1   ? $e  :(    $b     ? $f  :    $a ))); この可読性じゃインデントしても使えませんね・・・
guest

あなたの回答

tips

太字

斜体

打ち消し線

見出し

引用テキストの挿入

コードの挿入

リンクの挿入

リストの挿入

番号リストの挿入

表の挿入

水平線の挿入

プレビュー

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

ただいまの回答率
85.48%

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

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

質問する

関連した質問