2015-03-12 15 views
30

Trong khi làm việc thông qua các Scala exercises on Iterables, tôi gặp phải những hành vi kỳ lạ sau đây:Scala Sets chứa các yếu tố tương tự, nhưng sameElements() trả về false

val xs = Set(5,4,3,2,1) 
val ys = Set(1,2,3,4,5) 
xs sameElements ys  // true 

val xs = Set(3,2,1) 
val ys = Set(1,2,3) 
xs sameElements ys  // false - WAT?! 

Chắc chắn những Sets có những yếu tố giống nhau, và nên bỏ qua đặt hàng; và tại sao điều này làm việc như mong đợi chỉ cho các thiết lập lớn hơn?

+0

Sử dụng '==' để kiểm tra sự bình đẳng bất kể thứ tự và lặp lại. –

+0

Đó là một điểm tốt để so sánh 'Set's với nhau, mặc dù tôi chỉ nhận thấy rằng' List (1,2,3) == Vector (1,2,3) 'nhưng' List (1,2,3) ! = Đặt (1,2,3) 'và' Danh sách (1,2,3)! = Mảng (1,2,3) 'là một mỏ khác có tiềm năng! – DNA

+0

Và như Paul Draper chỉ ra trong các bình luận bên dưới, 'Array (1,2,3)! = Array (1,2,3)' !! – DNA

Trả lời

57

Thư viện bộ sưu tập Scala cung cấp các triển khai chuyên biệt cho Bộ ít hơn 5 giá trị (xem source). Các trình vòng lặp cho các triển khai này trả về các phần tử theo thứ tự mà chúng được thêm vào, thay vì thứ tự dựa trên hàm băm nhất quán được sử dụng cho các Bộ lớn hơn.

Hơn nữa, sameElements (scaladoc) được xác định trên Iterable s (được triển khai trong IterableLike - xem source); nó trả về true chỉ khi các trình vòng lặp trả về các phần tử giống nhau trong cùng một thứ tự.

Vì vậy, mặc dù Set(1,2,3)Set(3,2,1)phải là tương đương, vòng lặp của họ là khác nhau, do đó lợi nhuận sameElements sai.

Hành vi này đáng ngạc nhiên và được cho là lỗi vì vi phạm các kỳ vọng toán học cho một Tập hợp (nhưng chỉ dành cho các kích thước nhất định của Set!).

Như I.K. chỉ ra trong các ý kiến, == hoạt động tốt nếu bạn chỉ so sánh các Bộ với nhau, tức là Set(1,2,3) == Set(3,2,1). Tuy nhiên, sameElements là tổng quát hơn ở chỗ nó có thể so sánh các phần tử của bất kỳ hai vòng lặp nào. Ví dụ: List(1, 2, 3) == Array(1, 2, 3) là sai, nhưng List(1, 2, 3) sameElements Array(1, 2, 3) là đúng.

Tổng quát hơn, bình đẳng thể gây nhầm lẫn - lưu ý rằng:

List(1,2,3) == Vector(1,2,3) 
List(1,2,3) != Set(1,2,3) 
List(1,2,3) != Array(1,2,3)  
Array(1,2,3) != Array(1,2,3) 

Tôi có submitted a fix cho Scala exercises giải thích vấn đề sameElements.

+0

Bằng tên của phương thức, tôi hy vọng nó sẽ bỏ qua thứ tự bất kể loại bộ sưu tập. Ví dụ. Tôi mong đợi danh sách tương tự 'List (1,2,3) '(3,2,1)' để đánh giá 'true', bởi vì cả hai _contain cùng các elements_. Nếu thứ tự quan trọng, thì sự khác biệt dự định giữa 'sameElements' và' == 'là gì? –

+2

Tìm thấy tuyệt vời ... Trong một dự án lớn, một cái gì đó như thế này có thể khiến bất kỳ ai phát điên. Bạn đã nêu ra một vé cho điều này trong các vấn đề chính thức của scala. –

+1

Tôi yêu scala rất nhiều nhưng lỗi như thế này là không tốt. Tốt tìm. –

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