2017-01-20 25 views
6

Giả sử tôi có một mảng lớn, @stuff$thing và tôi muốn biết nếu $thing nằm trong @stuff. Cách tốt nhất để làm điều đó trong Perl 6 là gì? Và với "tốt nhất" tôi ngụ ý: thành ngữ, dễ đọc, biểu diễn; Không nhất thiết phải theo thứ tự đó.Perl 6: cách tốt nhất để kiểm tra xem một phần tử có nằm trong danh sách không?

Thực tế có hai trường hợp riêng biệt. Một là nơi bạn phải thực hiện rất nhiều kiểm tra cho các số khác nhau $thing s, trường hợp kia là nơi bạn chỉ thực hiện việc này một lần hoặc một vài lần.

Hãy xem xét trường hợp đầu tiên trước. Tôi nghĩ tôi biết câu trả lời đúng (hoặc một).

my $set-of-stuff = set @stuff; 
for @whatever -> $thing { 
    do-something-with($thing) if $thing ∈ $set of stuff; 
} 

Bạn thực sự có thể bỏ qua dòng đầu tiên và đơn giản nói ... if $thing ∈ @stuff, nhưng điều đó sẽ gần như chắc chắn có hiệu suất tồi tệ hơn nhiều, vì các thiết lập được tạo ra mỗi lần.

Nhưng bây giờ trường hợp thứ hai, tôi chỉ có một $thing để kiểm tra. Các giải pháp trên hoạt động, tất nhiên, nhưng tạo ra các thiết lập, chỉ để kiểm tra xem nó một lần, có vẻ như rất nhiều chi phí. Phím tắt

do-something-with($thing) if $thing ∈ @stuff; 

có ý nghĩa hơn một chút ở đây, vì chúng tôi chỉ gọi nó một lần. Tuy nhiên, chúng ta phải tạo một bộ cho một lần sử dụng. truyền thống hơn

Một chút là:

do-something-with($thing) if @stuff.grep($thing); 

Hoặc có khả năng nhanh hơn:

do-something-with($thing) if @stuff.first($thing); 

Nhưng điều này dường như ít thành ngữ, và chắc chắn là một trong những thứ hai ít có thể đọc hơn $thing ∈ @stuff.

Tôi không nghĩ có giải pháp khớp thông minh, đúng không? Chắc chắn điều này không hoạt động:

do-something-with($thing) if $thing ~~ @stuff; 

Bất kỳ suy nghĩ nào?

Trả lời

11

Phụ thuộc vào định nghĩa "tốt nhất" hoặc "thông minh" của bạn.

Nếu bạn đang nói về hiệu suất, tôi khá chắc chắn

@stuff.first($thing) 

là nhanh nhất.

Idiomatically, và gần gũi với các giải pháp trên, sẽ là:

$thing ~~ any @stuff 

trong đó có các tiềm năng của hiệu suất wallclock tốt hơn do auto-Threading.

Sử dụng các bộ để thực hiện việc này, làm cho mã trông gần hơn với logic chính thức. Nhưng nó sẽ không làm cho mọi việc nhanh hơn, bởi vì bộ cần phải được tạo ra (trừ khi nó có thể được tạo ra tại thời gian biên dịch).

Không chắc chắn có câu trả lời "tốt nhất" cho câu trả lời này.

+0

Cảm ơn, tôi đã nghĩ đến 'bất kỳ'.Tuy nhiên, theo kinh nghiệm của tôi, các nút giao tiếp trong các phiên bản Rakudo hiện tại rất chậm, vì vậy đó có lẽ không phải là một lựa chọn tốt (chưa). – mscha

+0

Và "tốt nhất" là gì? Vâng, điều đó phụ thuộc vào tình hình, tôi đoán vậy. Lý tưởng nhất, hiệu suất tốt nhất, thành ngữ (sic?) Và khả năng đọc, nhưng trong thực tế bạn phải thỏa hiệp. Bạn có thể hy sinh một số hiệu suất cho khả năng đọc, ví dụ, nhưng không nhiều. – mscha

+0

Thực ra '[email protected] ($ thing)' nên nhanh bằng '@ stuff.first ($ thing)' (bởi vì nó dừng sau khi nó tìm thấy thứ gì đó khớp) –

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