4

したがって、次のコードの機能とその理由は理解できますが、これを行うには別の方法があるはずです。

my @squares = map { $_ > 5 ? ($_ * $_) : () } @numbers;

基本的に次のように言える方法はありますか?

my @squares = map { if ($_ > 5) then ($_ * $_) } @numbers;

それとも、すべてのエントリに「ルール」を持たなければならないのでしょうか?

4

2 に答える 2

6

amon は多くの情報を提供してくれましたが、実際には質問に答えていませんでした。に相当する

map { $_ > 5 ? ($_ * $_) : () }

if条件演算子の代わりに使用することは

map { if ($_ > 5) { $_ * $_ } else { () } }

マップ式が値を返さないことはあり得ません。最後に評価された式を返します。句を削除するとelse、その式が比較になるため、削除した場合と同様になります

map { if ($_ > 5) { $_ * $_ } else { $_ > 5 } }

一度しか実行されない$_ > 5ので、それに近いと思います

map { ($_ > 5) && ($_ * $_) }

そうです、すべてのエントリにルールを設定する必要があります。そうしないことは不可能です。

于 2013-05-12T12:17:32.873 に答える
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)。

于 2013-05-12T06:45:18.157 に答える