2009-02-22 87 views

回答

24

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

此外,map允許一對多映射,所以它的表達式在列表上下文中,而不是grep表達式的標量上下文。 – ysth 2009-02-22 20:10:05

+0

@ysth:的確如此。我打算說一些關於map總是返回與列表參數相同數量的元素,但後來記住表達式可以返回一個或多個元素作爲列表。 – 2009-02-22 20:57:04

2

將grep想象成帶有過濾器的映射。地圖迭代,並提供了一個機會來處理每個項目。例如,這些兩行是等效的:

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

類似地,這兩個是相同的:

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

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

的grep提供到插入條件的能力,並因此成爲一個過濾器。

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來實現。

10

我發現它的認爲想在他們最普遍的形式約grep()map()有所幫助:

grep {BLOCK} LIST 
map {BLOCK} LIST 

grep()是一個過濾器:它返回從列表中哪些塊返回true項目的子集。

map()是一個映射函數:將LIST中的值發送到BLOCK,BLOCK返回0或更多值的列表;所有這些BLOCK呼叫的組合將是由map()返回的最終列表。

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() 
0

草率地說:grep給出了它的塊標量上下文,map給出了它的塊列表上下文。 (並且BLOCK foreach LIST給出了它的塊空白上下文。)

相關問題