@foo = (2, 3, 6, 7); # Void context - modify @foo in place
reject { $_ > 3 } @foo; # @foo is now (2, 3)
@foo = (2, 3, 6, 7); # Scalar context - modify @foo in place
$n = reject { $_ > 3 } @foo; # @foo is now (2, 3), $n is length of modified @foo
@foo = (2, 3, 6, 7); # Array context - return a modified copy of @foo
@cpy = reject { $_ > 3 } @foo; # @cpy is (2, 3), @foo is (2, 3, 6, 7)
实施:
sub reject(&\@) {
my ($block, $ary) = @_;
# Return a copy in an array context
return grep {! $block->() } @$ary if wantarray;
# Otherwise modify in place. Similar to, but not
# quite, how rb_ary_reject_bang() does it.
my $i = 0;
for (@$ary) {
next if $block->();
($ary->[$i], $_) = ($_, $ary->[$i]); # swap idiom to avoid copying
$i++; # possibly huge scalar
}
$#$ary = $i - 1; # Shorten the input array
# We differ from Array#reject! in that we return the number of
# elements in the modified array, rather than an undef value if
# no rejections were made
return scalar(@$ary) if defined(wantarray);
}
3条答案
按热度按时间fivyi3re1#
您可以使用Perl的
grep
,它的作用类似于反向拒绝:它将保留所有满足条件的项。因此reject x > 3
必须变为grep x <= 3
:条件不一定是数值比较,但可以是在布尔上下文中工作的任何内容,例如,与正则表达式匹配。
gzszwxb42#
正如其他答案所示,
grep
通常就是您所需要的全部。然而,使用perl原型可以编写一个函数,像ruby的
Array#reject!
:用法为:
实施:
iyzzxitl3#