これは私が書いたものです:
$Myprovince = (
($province == 6) ? "city-1" :
($province == 7) ? "city-2" :
($province == 8) ? "city-3" :
($province == 30) ? "city-4" : "out of borders"
);
しかし、すべてのフィールドで値city-4
を取得しました。 switch/if
の代わりに三項演算子を使用したいのは、実験してそれがどのように行われるかを確認したいためです。
このコードの何が問題になっていますか?
他の人はすでにそれを行う正しい方法を提案していますが、本当に三項演算子を使用したい場合は、括弧を次のように使用する必要があります:
$province = 7;
$Myprovince = (
($province == 6) ? "city-1" :
(($province == 7) ? "city-2" :
(($province == 8) ? "city-3" :
(($province == 30) ? "city-4" : "out of borders")))
);
三項演算子は、左から右に評価されます。したがって、式を適切にグループ化しないと、予期しない結果になります。
3項式の「スタック」を避けることをお勧めします。 1つのステートメント内で複数の三項演算子を使用する場合のPHPの動作は自明ではありません。
あなたのコードは実際には次のように評価されます:
(
(
(
$province == 6 ? "city-1" : $province == 7
) ? "city-2" :
$province == 8
) ? "city-3" : $province == 30
) ? "city-4" : "out of borders";
どこにあるべきか
$province == 6 ? "city-1" : (
$province == 7 ? "city-2" : (
$province == 8 ? "city-3" : (
$province == 30 ? "city-4" : "out of borders"
)
)
);
このコードは問題なく見えるかもしれませんが、誰かがそれを読んで、このコードが何をしているかを理解するのに必要な時間よりも多くの時間が必要になります。
あなたはこのようなものでうまくいくでしょう:
$map = array( 6 = >'city-1',
7 => 'city-2',
8 => 'city-3',
30 => 'city-4');
$Myprovince = "out of borders";
if(array_key_exists($province, $map)) {
$Myprovince = $map[$province];
}
または、コメントで言及されている @ Jonah のように:
$Myprovince = isset($map[$province]) ? $map[$province] : 'out of borders';
そのようなことのために三項演算子を乱用しないでください。これはデバッグをほぼ不可能にします。のようなことをしてみませんか
switch($province) {
case 6: $Myprovince = "city-1"; break;
case 7: ...
}
または単にチェーンされたif/then/else
if ($province == 6) {
$Myprovince = "city-1";
} elseif ($province = ...) {
...
}
一部の人々は、switchステートメントまたはif/elseステートメントの使用を提案しています。しかし、代わりに配列を使用して、保守と読み取りを容易にします。
$provinces = array (
6 => 'city-1',
7 => 'city-2',
8 => 'city-3',
30 => 'city-4'
);
// then you can call:
$Myprovince = isset($provinces[$province]) ? $provinces[$province] : 'out of borders';
コードはおそらく最終的には管理しやすくなります。多分あなたはそれらの州から都市へのマッピングをデータベースからいつか追加したいと思うでしょう。
これはPHPに関する質問であることを理解していますが、これは単なる教育的な演習なので、RubyとJavaScriptが実際に期待どおりに動作することを学習することに興味があると思います。
ルビー:
ree-1.8.7-2012.02 :009 > def foo x
ree-1.8.7-2012.02 :010?> x == 1 ? "city 1" : x == 2 ? "city 2" : "out of borders"
ree-1.8.7-2012.02 :011?> end
=> nil
ree-1.8.7-2012.02 :012 > foo 1
=> "city 1"
ree-1.8.7-2012.02 :013 > foo 2
=> "city 2"
ree-1.8.7-2012.02 :014 > foo 3
=> "out of borders"
JavaScript:
> function f(x) { return x == 1 ? "city 1" : x == 2 ? "city 2" : "out of borders"; }
undefined
> f(1)
"city 1"
> f(2)
"city 2"
> f(3)
"out of borders"
かっこを追加してみてください:
$Myprovince = (
($province == 6) ? "city-1" :
(($province == 7) ? "city-2" :
(($province == 8) ? "city-3" :
(($province == 30) ? "city-4" : "out of borders"
))));
コードに三項演算子の優先順位に関する問題があります。
しかし、この演算子を本当に削除して、代わりにswitch
を使用するようにすべきだと思います。
今日も同じ問題に巻き込まれました。他はすでに許容できる解決策を与えています。 1つのライナーのifsだけに重点を置きます。私の意見ではもっと読みやすいです。
if ($province == 6) $Myprovince = 'city-1';
elseif ($province == 7) $Myprovince = 'city-2';
elseif ($province == 8) $Myprovince = 'city-3';
elseif ($province == 30) $Myprovince = 'city-4';
else $Myprovince = 'out of borders';
代わりにスイッチを使用してください。三元演算子は、すぐに理解するのが非常に難しくなるため、実際には単一の条件以上に使用するべきではありません。
switch ($province) {
case 6:
$Myprovince = 'city-1';
break;
case 7:
$Myprovince = 'city-2';
break;
case 8:
$Myprovince = 'city-3';
break;
case 30:
$Myprovince = 'city-4';
break;
default:
$Myprovince = 'out of borders';
}