2008-08-15 48 views
5

Khi tôi đang chạy tuyên bố sau:Tại sao bản đồ Perl của tôi không trả lại bất cứ điều gì?

@filtered = map {s/ //g} @outdata; 

nó được trả lại một danh sách trống thay vì danh sách lọc mà tôi mong đợi. Những gì tôi đang cố gắng làm là loại bỏ mọi sự xuất hiện của   từ một mảng chuỗi (là một tệp XML).

Rõ ràng, tôi không hiểu điều gì đó. Bất cứ ai có thể cho tôi biết cách chính xác để làm điều này có thể được, và tại sao điều này không làm việc cho tôi như là?

+0

này liên quan đến http://stackoverflow.com/questions/1458454/why-is-the-list-my-perl-map-returns-just-1s/1461242#1461242, và nó có Cùng một câu trả lời. –

Trả lời

10

Hãy thử điều này:

@filtered = map {s/ //g; $_} @outdata; 

Vấn đề là các nhà điều hành trong s perl đổi $ _ nhưng thực sự trả về số thay đổi nó làm. Vì vậy, $ _ thêm vào cuối sẽ làm cho perl trả về chuỗi đã sửa đổi cho mỗi phần tử của @outdata.

+5

Mã này trashes các giá trị trong @ outdata. –

+6

Tôi không cảm thấy có ý nghĩa đủ để downvote, nhưng đây là một ý tưởng tồi. http://stackoverflow.com/questions/12103/why-doesnt-my-perl-map-return-anything/21792#21792 là câu trả lời hay hơn nhiều. –

+0

Với [Thay thế không phá hủy của Perl 5.14] (http://www.effectiveperlprogramming.com/2010/09/use-the-r-substitution-flag-to-work-on-a-copy/), bạn có thể thực hiện điều này như '@filtered = map {s/  // gr} @ outdata' mà không ảnh hưởng đến' @ outdata'. –

3

Trái với những câu trả lời của Greg, bạn có thể lạm dụng grep:

@filtered = grep {s/ //g; 1} @outdata; 

Đừng làm điều này.

15

Lưu ý rằng bản đồ cũng sẽ sửa đổi mảng nguồn của bạn. Vì vậy, bạn có thể làm:

map {s/ //g} @outdata; 

và bỏ qua biến @filtered hoàn toàn, hoặc nếu bạn cần phải giữ lại bản gốc,

@filtered = @outdata; 
map {s/ //g} @filtered; 

Mặc dù, trong trường hợp đó, nó có thể là dễ đọc hơn để sử dụng foreach:

s/ //g foreach @filtered; 
+0

'map' trong void context thường được coi là nghèo form và không nói bất cứ điều gì trên' cho @filtered {...} '. –

6

Để theo dõi điểm Tithonium, điều này cũng sẽ làm các trick:

@filtered = map {local $_=$_; s/ //g; $_} @outdata; 

"địa phương" đảm bảo bạn đang làm việc trên một bản sao chứ không phải bản gốc.

9

Câu trả lời của Greg có vấn đề là nó sẽ sửa đổi mảng ban đầu khi $ _ được chuyển bí danh. Bạn cần:

@filtered = map { (my $new = $_) =~ s/ //g; $new} @outdata; 
4
use Algorithm::Loops "Filter"; 
@filtered = Filter { s/ //g } @outdata; 
Các vấn đề liên quan