いまさらながら、コメントで頂いたperlのコード(grep)を試してみた

4ヶ月近く前、pythonのコードすげーって記事(ループで配列を作る書き方)を書いたのだけど、

それにたいして、perlだとこう書けるよというコメントを頂いていた。

id:tkmc
perlだとこんな感じ?
return grep $_, @array;

そのときは、「へ〜」くらいに思っていたのだけど、
いまさら本当にこれで動くのか疑問に思ったので、確認しつつメモ。


ちなみに、期待する動作は、配列から空文字要素を落とすというもの。


実際に、適当に配列を作ってやってみる。

my @array = (1, '', 'a');
@array = grep $_, @array;
print join(',', @array),"\n";

>> 1,a

ちゃんと動いてる。


grepの第1引数が正規表現ではない場合の使い方をしたことがなかったので、
なぜこのような動作をするのかすぐにはピンとこなかったけど、結局こういうことらしい。

my @temp;
for (@array) {
    push(@temp, $_) if $_;
}
@array = @temp;


なので、揚げ足を取るようではあるが、頂いたコメントのコードは厳密には正しくない。
要素に0とか'0'があった場合に、空文字ではないのに落としてしまうからである。

my @array = (1, 0, 'a', '', '0');
@array = grep $_, @array;
print join(',', @array),"\n";

>> 1,a


たぶん、こんな感じにすれば問題ないと思う。

my @array = (1, 0, 'a', '', '0');
@array = grep $_ ne '', @array;
# あるいは  @array = grep length($_), @array;
print join(',', @array),"\n";

>> 1,0,a,0


ま、arrayの要素に0とか'0'なんて入らない前提があれば、コメントのコードでまったく問題ないのだが。