2010-08-26 45 views
13

Trong Perl, bạn có thể tùy ý kết thúc việc thực thi map, ví dụ: một cái gì đó tương đương với last trong một vòng lặp?Có cái gì đó giống như `last` cho` map`?

Nó sẽ là một chút như thế này:

map { 
    if (test == true) { last; } dosomething 
} @myarray 
+4

Xem [Là "bản đồ" một vòng lặp?] (Http://stackoverflow.com/questions/3019925/is-map-a-loop) cho một câu hỏi liên quan. – Zaid

Trả lời

19

Nope. Bạn không thể last, next, v.v. trong số map, grep hoặc sort khối vì they are not loops.

Có nói rằng, đoạn mã trong câu hỏi là thực hành kém bởi vì map không bao giờ nên được gọi trong ngữ cảnh trống. Chúng được cho là được sử dụng để biến đổi một danh sách thành một danh sách khác.

Dưới đây là một cách tốt hơn để viết nó nếu bạn thực sự phải inline nó (sửa đổi sau khi bình luận ysth của):

$_ == 10 && last, print for 1..15; # prints '123456789' 
+0

cảm ơn bạn đã trả lời. Về điều "parctice nghèo", vâng ... đoạn mã "dosomething" được thiết kế để .... làm điều gì đó – benzebuth

+6

@ benzebuth: Tôi không nói về 'do_something'. Bạn nên thực sự đang sử dụng 'map' để trả về một danh sách. – Zaid

+0

cảm ơn. Giờ thì tôi đã hiểu. Rất hữu ích thực sự. +1 – benzebuth

3

số Sử dụng một foreach vòng lặp thứ và last tuyên bố.

Kể từ 5.8.1, map is context aware - trong ngữ cảnh trống, không có danh sách nào được tạo. Dù sao, bản đồ thường được sử dụng để lấy danh sách từ danh sách khác, đánh giá expr cho từng phần tử của danh sách gốc.

2

Bạn có thể sử dụng một bước nhảy dài (eval/die cặp) để giải cứu của bất kỳ cấu trúc lồng nhau mà không trực tiếp hỗ trợ nó:

eval { map{ die if test; dosomething } @myarray }; 

Nhưng khi Zaid cho biết, sử dụng một vòng lặp for/foreach trong trường hợp này tốt hơn vì bạn không sử dụng giá trị trả lại là map.

+0

bản đồ không xây dựng danh sách trong ngữ cảnh trống: http://perldoc.perl.org/perlfaq6.html#What%27s-wrong-with-using-grep-in-a-void-context? –

+0

@eugene => đó là sự thật, nhưng nó là một chút sai lầm để sử dụng 'bản đồ' mà không có giá trị trả lại. nếu bạn muốn vị trí ngược của hành động và giá trị, tốt hơn là sử dụng 'dosomething for ... ' –

+0

ngoại lệ là khi bạn vì một lý do nào đó muốn cung cấp ngữ cảnh danh sách dosomething (nhưng không thực sự muốn danh sách trả về) - trường hợp hiếm. để cung cấp ngữ cảnh void cho dosomething (và grep sẽ cung cấp ngữ cảnh vô hướng) – ysth

2

Bạn muốn có một vòng lặp for:

foreach (@myarray) { 
    last if test; 
    ... 
} 

Nó làm điều tương tự. map là để chuyển đổi một danh sách thành các danh sách khác.

3

Bạn có thể sử dụng một do-block với một cho sửa đổi tuyên bố:

do { 
    last if test; 
    dosomething; 
} for (@myarray); 

Mặc dù sử dụng một khối foreach có lẽ sẽ rõ ràng hơn, và tương lai bảo trì mã của bạn sẽ cảm ơn bạn.

foreach (@myarray) { 
    last if test; 
    dosomething; 
} 
1

Có cấu trúc giống như bản đồ thực hiện chính xác những gì bạn muốn làm. Hãy nhìn vào List::UtilList::MoreUtils (thuận tiện cũng được đóng gói với nhau như List::AllUtils):

use List::MoreUtils 'first'; 

# get first element with a {foo} key 
my $match = map { $_->{foo} eq 'some string' } @elements; 

Nếu bạn không muốn trích xuất một phần tử (s) từ danh sách, sau đó sử dụng foreach, theo các câu trả lời trước.

-1

Hãy thử goto LABEL. Tuy nhiên tôi không biết làm thế nào là an toàn.

+0

Ai đó đã gắn cờ điều này là không phải là câu trả lời, nhưng điều này có vẻ ổn với tôi. Nó có lẽ không phải là câu trả lời hay nhất, vì nó không có phiếu bầu và các câu trả lời khác có tấn, nhưng điều đó không đảm bảo gọi đó không phải là câu trả lời. – ArtOfWarfare

+1

Đây là câu trả lời có chất lượng rất thấp trên một bài đăng ** năm cũ ** có nhiều câu trả lời hay hơn ... không có gì thêm cho câu hỏi này và IMHO nên được downvoted và cuối cùng bị xóa. – Frazz

+0

Nó có thể là "chất lượng thấp", nhưng nó không phải là VLQ. Chỉ cần downvote và để nó lại. – JasonMArcher

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