したがって、次のコードの機能とその理由は理解できますが、これを行うには別の方法があるはずです。
my @squares = map { $_ > 5 ? ($_ * $_) : () } @numbers;
基本的に次のように言える方法はありますか?
my @squares = map { if ($_ > 5) then ($_ * $_) } @numbers;
それとも、すべてのエントリに「ルール」を持たなければならないのでしょうか?
したがって、次のコードの機能とその理由は理解できますが、これを行うには別の方法があるはずです。
my @squares = map { $_ > 5 ? ($_ * $_) : () } @numbers;
基本的に次のように言える方法はありますか?
my @squares = map { if ($_ > 5) then ($_ * $_) } @numbers;
それとも、すべてのエントリに「ルール」を持たなければならないのでしょうか?
amon は多くの情報を提供してくれましたが、実際には質問に答えていませんでした。に相当する
map { $_ > 5 ? ($_ * $_) : () }
if
条件演算子の代わりに使用することは
map { if ($_ > 5) { $_ * $_ } else { () } }
マップ式が値を返さないことはあり得ません。最後に評価された式を返します。句を削除するとelse
、その式が比較になるため、削除した場合と同様になります
map { if ($_ > 5) { $_ * $_ } else { $_ > 5 } }
一度しか実行されない$_ > 5
ので、それに近いと思います
map { ($_ > 5) && ($_ * $_) }
そうです、すべてのエントリにルールを設定する必要があります。そうしないことは不可能です。
これが機能するには、map
ブロックは不要なアイテムの空のリストを返す必要があります。コードを で書き換える間grep
、
my @squares = map { $_**2 } grep { $_ > 5 } @numbers;
これは多くの優雅さを失います。
else
戻り値を指定しないif
と、暗黙的に false 値が渡されるように見えます。
say $_+0 for map{ if($_>5){$_**2} } 3..7;
# 0
# 0
# 0
# 36
# 49
これは私たちの目的には役に立ちません。
しかし、ブロックの値を返すフィルタリング マップ、または false の場合は空のリストをいつでも書くことができます。
sub mapgrep (&@) {
my $cb = shift;
map { local $_ = $_; $cb->($_) || () } @_;
}
my @squares = mapgrep { $_**2 if $_ > 5 } @numbers;
ただし、これは、この状態が別の方法で処理されない場合、条件が条件の値を返すという副作用に依存しています。これが明示的に文書化されている場所がわかりません。
(注: Perl にはキーワードがありませんthen
)。