Perl中的grep和map有什么区别?

时间:2009-02-22 19:11:25

标签: perl map grep

在Perl中,grepmap都使用表达式和列表,并为列表中的每个元素计算表达式。

两者有什么区别?

6 个答案:

答案 0 :(得分:25)

grep返回原始列表中与表达式匹配的元素,而map返回应用于原始列表的每个元素的表达式的结果。

$ perl -le 'print join " ", grep $_ & 1, (1, 2, 3, 4, 5)'
1 3 5
$ perl -le 'print join " ", map $_ & 1, (1, 2, 3, 4, 5)'
1 0 1 0 1

第一个示例打印列表中的所有奇数元素,而第二个示例打印0或1,具体取决于相应元素是否为奇数。

答案 1 :(得分:10)

我发现以最常见的形式思考grep()map()是有帮助的:

grep {BLOCK} LIST   
map  {BLOCK} LIST

grep()是一个过滤器:它返回LIST中BLOCK返回true的项子集。

map()是一个映射函数:将一个值从LIST发送到BLOCK,BLOCK返回一个包含0个或更多值的列表;所有这些BLOCK调用的组合集将是map()返回的最终列表。

答案 2 :(得分:4)

map将函数应用于列表中的所有元素并返回结果。

grep返回列表中的所有元素,当函数应用于它们时,这些元素的计算结果为true。

my %fruits = (
  banana => {
    color => 'yellow',
    price => 0.79,
    grams => 200
  },
  cherry => {
    color => 'red',
    price => 0.02,
    grams => 10
  },
  orange => {
    color => 'orange',
    price => 1.00,
    grams => 225
  }
);

my %red_fruits = map { $_ => $fruits{$_} }
                   grep { $fruits{$_}->{color} eq 'red' }
                     keys(%fruits);

my @prices = map { $fruits{$_}->{price} } keys(%fruits);
my @colors = map { $fruits{$_}->{color} } keys(%fruits);
my @grams  = map { $fruits{$_}->{grams} } keys(%fruits);

# Print each fruit's name sorted by price lowest to highest:
foreach( sort { $fruits{$a}->{price} <=> $fruits{$b}->{price}} keys(%fruits) )
{
  print "$_ costs $fruits{$_}->{price} each\n";
}# end foreach()

答案 3 :(得分:3)

关于grep的另一件事:在标量上下文中它告诉你它找到了多少项。如果你真的不想要第二个列表,这可能很有用,但你确实想知道某种类型的项目有多少。

my @numbers = qw/1 2 3 4 5 6/;

my @odd_numbers  = grep { $_ & 1 } @numbers; # grep returns (1, 3, 5)

my $how_many_odd = grep { $_ & 1 } @numbers; # grep returns 3

编辑:由于OP在评论中提到,我应该说你可以以相同的方式在标量上下文中使用map。关键不在于grep是两者中唯一可以做到这一点的人,但有时用grep来做这件事就很方便了。

答案 4 :(得分:2)

将grep视为带过滤器的地图。 map迭代并提供对每个项目执行某些操作的机会。例如,这两行是等价的:

my @copy = @original;
my @copy = map {$_} @original;

同样,这两者是等价的:

my @copy = grep {-f $_} @original;

@copy = ();
for (@original)
{
  push @copy, $_ if -f $_;
}

grep提供插入条件的功能,因此成为过滤器。

答案 5 :(得分:0)

面对面:grep给出了它的块标量上下文,map给出了它的块列表上下文。 (并且BLOCK foreach LIST给出了它的块无效上下文。)