有限リンクトリストのgrep,filter
mapの次はgrep.名前をfilterにします.
sub filter(&$){ my ($f,$l) = @_; return unless $l; my $temp=head($l); if ($f->($temp)){ node($temp, &filter($f,tail($l))); }else{ &filter($f,tail($l)); } }
filterはリンクトリストのノードを一個一個たどっていき,無名サブルーチンで与えられる条件が真(0以外の値を返す)ときに,新しいノードに出すようにしています.条件が偽のときは,tailをfilterに渡すことでそのノードをスキップしています.
Higher-Order Perlではこのスキップの処理を別に行うことで,filterの呼び出し回数を減らしていますが,愚直な方法でいきましょう.
実行すると以下のようになります.
my $a=[ 1, [2, [ 3, [4,undef ] ] ] ]; print Dumper (filter {$_[0] % 2} $a); $VAR1 = [ 1, [ 3, undef ] ];
「2で割ったあまりが0ではない」すなわち「奇数」を取り出しています.