2017-12-06 57 views
7

Tài liệu Perl6 chỉ ra rằng khi so sánh hai mục trong một tập hợp, === được sử dụng. Đây là trích dẫn từ tài liệu perl6:perl6 Chức năng so sánh do người dùng xác định trong các phép tính đã đặt

Đối tượng/giá trị thuộc bất kỳ loại nào được phép làm thành phần được đặt. Trong vòng một Set, mọi phần tử được đảm bảo là duy nhất (theo nghĩa là không có hai yếu tố sẽ so sánh một cách tích cực với các nhà điều hành ===)

Tôi tự hỏi nếu nó có thể sử dụng một chức năng người dùng định nghĩa thay vì của ===? Ví dụ: Làm cách nào tôi có thể sử dụng ~~ thay vì === để xác định xem 2 phần tử trong một tập hợp có "bằng nhau" hay không.

Vấn đề tôi đang cố gắng giải quyết là: tập A có một số tên và một số họ trong bất kỳ thứ tự nào nhưng tất cả chữ thường và không có dấu chấm câu, và đặt B có một số tên và họ. thứ tự, và có thể có dấu chấm câu gắn liền với tên và có thể là trường hợp trên hoặc dưới. Tôi muốn biết nếu một người trong bộ A (đại diện như một tập hợp con của A với một họ và tên cụ thể) xuất hiện trong tập B. Trong trường hợp này, tôi không thể sử dụng === vì các chữ cái và dấu chấm câu trong tập B.

Nếu tôi có thể sử dụng ~~ thay vì ===, vấn đề sẽ đơn giản hơn nhiều vì tôi chỉ cần xác định xem tập hợp con của A cũng là tập con của B sử dụng ~~. Điều này tương tự như một vấn đề "hoán vị phù hợp" mà tôi đã đề cập trước đây.

Cảm ơn bạn rất nhiều!

+1

Điều này cũng rất phù hợp để kiểm tra tư cách thành viên của danh sách: '$ foo ∈ @ array' sử dụng' === '. Và '===' dường như sử dụng hàm '.WHICH'. Đó là một vấn đề quan trọng bởi vì một số đối tượng không có ID '.WHICH' có thể dự đoán, như' Pair', sẽ có một '.WHICH' khác nhau tùy thuộc vào việc bạn viết các phần tử dưới dạng giá trị hay biến. Vì vậy, bạn có thể kết thúc với '(1 => 2) ∉ [1 => 2, 3 => 4]' tùy thuộc vào việc cấu trúc dữ liệu đã được tạo với biến hay giá trị không chứa. – piojo

+0

Bạn có thể đưa ra một ví dụ ngắn về một người, một bộ A có thể và một bộ B có thể không? Hay chỉ là một người và một bộ B? – piojo

+0

Tôi đang xem liệu việc sử dụng tính năng 'Pair.value' trong tài khoản khi tạo' Pair.WHICH' có đúng hay không. –

Trả lời

5

Có một vài cách và tôi sẽ bắt đầu với cách dễ dàng/chậm. Tôi sẽ sử dụng toán tử ==, nhưng bạn có thể sử dụng bất kỳ thao tác nào. Nếu bạn muốn lặp qua danh sách/tập hợp, bạn có thể sử dụng first với bất kỳ logic phù hợp nào mà bạn thích, sau đó kiểm tra .defined để xác nhận rằng bạn đã khớp. (Nếu bạn muốn thực sự cẩn thận hoặc nếu danh sách của bạn chứa các mục không xác định, bạn nên sử dụng trạng thái :p để đầu ra của bạn là cặp khóa/giá trị và sẽ được xác định khi và chỉ khi tìm thấy một số phần tử phù hợp.)

đối với một ví dụ về hợp luộm thuộm sử dụng kỹ thuật này, tôi sẽ tìm kiếm một số trong một danh sách và tập hợp các IntStr:

say 4 ∈ ("3", "4"); # False, because the list doesn't contain the integer 4 
say ("3", "4").first(* == 4, :p).defined; # True 
say set("3", "4").keys.first(* == 4, :p).defined; # True 

Bạn sẽ phải chuẩn để biết liệu đây là nhanh như việc kiểm tra thiết lập thành viên theo cách thông thường hơn. Đối với một tập hợp lớn, các cách thông thường sẽ nhanh hơn, vì tra cứu băm có thể được sử dụng. Trong một số ngôn ngữ lập trình, lặp lại nhanh hơn băm cho đến khi danh sách trở nên thực sự lớn.

Nếu bạn không cần phải nhận được các yếu tố phù hợp, bạn có thể sử dụng nút giao thông, mà sẽ làm nhiều kiểm tra song song:

say so ("3", "4").any() == 4; # True 

Và bạn có thể sử dụng nút giao thông để làm thử nghiệm tập hợp con là tốt, nhưng kể từ khi đây là một hoạt động O (m * n) (mặc dù được tự động tạo luồng), không mong đợi hiệu suất cao khi so sánh hai bộ rất lớn.

say so (2, 3).all() == ('1', '2', '3').any(); # True 
say so (2, 3, 4).all() == ('1', '2', '3').any(); # False 

Tôi đã sử dụng danh sách thay vì các bộ ở trên, vì nếu bạn không sử dụng toán tử/phương pháp chuẩn, bộ không cung cấp tốc độ hoặc lợi thế API.

+0

Cảm ơn bạn rất nhiều, piojo !! Tôi sẽ cố gắng điều chỉnh các đề xuất của bạn để đạt được giải pháp. Cảm ơn !! – lisprogtor

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