有限リンクトリストの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ではない」すなわち「奇数」を取り出しています.