2009-02-22 41 views

Trả lời

24

grep trả lại các phần tử của danh sách gốc khớp với biểu thức, trong khi map trả về kết quả của biểu thức được áp dụng cho từng phần tử trong danh sách gốc.

$ 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 

Ví dụ đầu tiên in tất cả các phần tử lẻ của danh sách, trong khi ví dụ thứ hai in 0 hoặc 1 tùy thuộc vào phần tử tương ứng có lẻ hay không.

+1

Ngoài ra, bản đồ cho phép ánh xạ một-nhiều, vì vậy biểu thức của nó nằm trong ngữ cảnh danh sách, chứ không phải ngữ cảnh vô hướng của biểu thức grep. – ysth

+0

@ysth: Đúng vậy.Tôi sẽ nói điều gì đó về bản đồ luôn luôn trả về cùng một số yếu tố như đối số danh sách của nó, nhưng sau đó nhớ rằng biểu thức có thể trả về không hoặc nhiều hơn một phần tử làm danh sách. –

2

Hãy suy nghĩ về grep làm bản đồ với bộ lọc. bản đồ lặp lại và cung cấp một cơ hội để làm điều gì đó với mọi mục. Ví dụ hai dòng sau là tương đương:

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

Tương tự, hai là tương đương:

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

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

grep cung cấp khả năng chèn một điều kiện, và do đó trở thành một bộ lọc.

3

Một điều khác về grep: trong ngữ cảnh vô hướng, nó cho bạn biết có bao nhiêu mục được tìm thấy. Điều này có thể hữu ích nếu bạn không thực sự muốn một danh sách thứ hai, nhưng bạn muốn biết có bao nhiêu mục của một loại nhất định có.

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 

Chỉnh sửa: Vì OP hỏi trong nhận xét, tôi nên nói rằng bạn có thể sử dụng map trong ngữ cảnh vô hướng theo cùng một cách. Điểm không phải là grep là chỉ một trong hai có thể làm điều này, nhưng đôi khi nó có ích để làm điều này với grep.

+0

không bản đồ làm tương tự trong bối cảnh vô hướng? –

+0

Có. Tôi không ngụ ý ngụ ý rằng chỉ grep mới làm được điều này - đó chỉ là một tính năng hay mà đôi khi mọi người không biết. (Ngoài ra, tôi thực sự không thể nghĩ ra một trường hợp mà tôi muốn sử dụng bản đồ trong ngữ cảnh vô hướng.) – Telemachus

+0

cảm ơn vì đã làm rõ điều đó :) –

10

tôi thấy rằng nó rất hữu ích để suy nghĩ suy nghĩ về grep()map() ở dạng chung nhất của họ:

grep {BLOCK} LIST 
map {BLOCK} LIST 

grep() là một bộ lọc: nó trả về tập hợp con của các mục từ DANH mà BLOCK trả về true.

map() là hàm ánh xạ: gửi giá trị từ LIST vào BLOCK và BLOCK trả về danh sách gồm 0 giá trị trở lên; tập hợp kết hợp tất cả các cuộc gọi đến BLOCK sẽ là danh sách cuối cùng được trả về bởi map().

4

map áp dụng một chức năng cho tất cả các phần tử trong danh sách và trả về kết quả.

grep trả về tất cả các phần tử trong danh sách đánh giá đúng khi một hàm được áp dụng cho chúng.

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

Facetiously: grep cung cấp ngữ cảnh vô hướng khối, bản đồ cho ngữ cảnh danh sách chặn của nó. (Và BLOCK foreach LIST đưa ra bối cảnh void block của nó.)

Các vấn đề liên quan