2011-11-10 13 views
43

Có cách nào dễ dàng để chuyển đổi một phân loại chữ hoa thành một tuple không?Trong Scala, có cách nào dễ dàng để chuyển đổi một lớp chữ thường thành một tuple không?

Tôi có thể, tất nhiên, dễ dàng viết mã bản mẫu để làm điều này, nhưng ý tôi là không có bản mẫu.

Điều tôi thực sự sau là cách dễ dàng tạo một lớp chữ điển theo thứ tự từ điển. Tôi có thể đạt được mục tiêu cho các bộ dữ liệu bằng cách nhập scala.math.Ordering.Implicits._, và thì đấy, các bộ dữ liệu của tôi có một Ordering được định nghĩa cho chúng. Tuy nhiên, hàm ý trong scala.math.Ordering không hoạt động đối với các trường hợp nói chung.

Trả lời

64

Làm thế nào để gọi unapply().get() trong đối tượng đồng hành?

case class Foo(foo:String, bar:Int) 

val (str, in) = Foo.unapply(Foo("test", 123)).get() 
+3

cảm ơn lời khuyên, trong REPL 2.9.0-1 tôi đã phải xóa() để "nhận" – Tanjona

+0

rất tuyệt! Tôi không có ý tưởng nào về việc không thích hợp –

+0

Thật tuyệt vời! Với đề nghị của bạn tôi đã có thể nhận được trường hợp của tôi lớp Ordered như vậy: 'val thisTuple: Ordered [(String, Int)] = Foo.unapply (this) .get; val thatTuple = Foo.unapply (đó) .get; thisTuple so sánh thatTuple'. Đó không phải là điều đẹp nhất trên thế giới, vì vậy tôi vẫn mở để gợi ý, nhưng câu trả lời của bạn chắc chắn sẽ hoàn thành công việc. Cảm ơn! – Douglas

3

Bạn có thể thử mở rộng ProductN đặc điểm, cho N = 1-22, mà TupleN kéo dài. Nó sẽ cung cấp cho bạn rất nhiều ngữ nghĩa Tuple, như các phương thức _1, _2, v.v. Tùy thuộc vào bạn cách bạn sử dụng các loại của bạn, điều này có thể là đủ mà không cần tạo một Tuple thực tế.

+0

Tôi không biết cách làm thế nào để phương pháp này hoạt động cho tôi. Tôi muốn lớp trường hợp của tôi hoặc được theo thứ tự từ điển hoặc có một thứ tự từ điển, mà không cần phải viết nhiều bản mẫu. Việc mở rộng ProductN dường như không hoạt động với các hàm implic trong scala.math.Ordering cho phép người dùng dễ dàng cung cấp cho bộ dữ liệu một thứ tự từ điển. – Douglas

0

Đến ngang qua chuỗi cũ này trong khi cố gắng làm điều tương tự. Cuối cùng tôi đã giải quyết về giải pháp này:

case class Foo(foo: String, bar: Int) 

val testFoo = Foo("a string", 1) 

val (str, in) = testFoo match { case Foo(f, b) => (f, b) } 
0

Shapeless sẽ làm điều này cho bạn.

import shapeless._ 
    import shapeless.syntax.std.product._ 

    case class Fnord(a: Int, b: String) 

    List(Fnord(1, "z - last"), Fnord(1, "a - first")).sortBy(_.productElements.tupled) 

Gets

res0: List[Fnord] = List(Fnord(1,a - first), Fnord(1,z - last)) 

productElements biến một lớp hợp thành một hình thù HList:

scala> Fnord(1, "z - last").productElements 
res1: Int :: String :: shapeless.HNil = 1 :: z - last :: HNil 

Và HLists được chuyển đổi thành bộ dữ liệu với #tupled:

scala> Fnord(1, "z - last").productElements.tupled 
res2: (Int, String) = (1,z - last) 

Performance có thể là horri ble, vì bạn liên tục chuyển đổi. Bạn có lẽ sẽ chuyển đổi mọi thứ thành dạng tupled, sắp xếp, sau đó chuyển đổi nó trở lại bằng cách sử dụng một cái gì đó như (Fnord.apply _).tupled.