2011-07-16 39 views
6

Tôi muốn chuyển đổi một giá trị thành một tập hợp nhiều "đặc điểm", mà không sử dụng cấu trúc dữ liệu có thể thay đổi để thu thập các giá trị. Tôi muốn một cái gì đó giống như cấu trúc tưởng tượng này trong đó sử dụng mô hình kết hợp, nhưng không dừng lại sau trận đấu đầu tiên:Cách thành ngữ để chuyển đổi A => Seq [B]

scala> 2 multimatch { 
    case i if i > 0 => "Positive" 
    case i if i < 0 => "Negative" 
    case i if (i % 2 == 0) => "Even" 
    //yadda yadda 
} 
res0: Seq[java.lang.String] = List(Positive, Even) 
+0

Chỉ một trường hợp có thể khớp. Bạn cần phải lồng ghép chúng để 2 có thể được nhận diện là tích cực và thậm chí, hoặc tôi đang thiếu điểm ở đây? – agilesteel

+0

Vâng, tôi mô tả một cái gì đó tương tự như khớp mẫu, trong đó> 1 kết quả phù hợp có thể được trả lại. –

Trả lời

21

Sử dụng mô hình ma cô, chức năng từng phần và các thông số lặp đi lặp lại, đây là cách gần tôi có thể nhận được:

class MultiMatcher[A](a: A) { 
    def multiMatch[B](pfs: PartialFunction[A, B]*): Seq[B] = { 
    pfs.map(_.lift(a)).collect{ case Some(v) => v } 
    } 
} 

implicit def toMultiMatcher[A](a:A): MultiMatcher[A] = new MultiMatcher(a) 

2 multiMatch (
    { case i if i > 0 => "Positive" }, 
    { case i if i < 0 => "Negative" }, 
    { case i if i % 2 == 0 => "Even" } 
) 
// returns Seq[java.lang.String] = ArrayBuffer(Positive, Even) 
+0

Tuyệt! Chúng ta nên có điều này lib Scala ... – Landei

+0

Tại sao không 'pfs.flatMap (_. Lift (a))'? –

+0

Chuyển đổi ngầm định hiện là 'chọn tham gia', vì vậy hãy thêm 'nhập scala.language.implicitConversions' trước khi xác định chuyển đổi ẩn. –

8

Trước tiên, bạn xác định đặc điểm của bạn như các chức năng từ Int để lựa chọn [Chuỗi]

val pos = (i:Int) => if (i > 0) Some("Positive") else None 
val neg = (i:Int) => if (i < 0) Some("Negative") else None 
val even = (i:Int) => if (i % 2 == 0) Some("Even") else None 

Sau đó, bạn tạo một danh sách các đặc điểm.

val characteristics = pos::neg::even::Nil 

Và sau đó bạn sử dụng sơ đồ phẳng để có danh sách những đặc điểm áp dụng cho một đối tượng nhất định.

scala> characteristics.flatMap(f=>f(2)) 
res6: List[java.lang.String] = List(Positive, Even) 
2

Đầu tiên, định nghĩa một hàm multimatch như sau:

scala> def multimatch[A,B](value : A,ps: (A => Boolean, B)*) = 
    |   for (p <- ps 
    |     if (p._1(value))) yield p._2 
multimatch: [A,B](value: A,ps: ((A) => Boolean, B)*)Seq[B] 

Sau đó, , ở đây chúng tôi đi:

scala> multimatch(2, 
     |   (((x :Int) => x > 0) -> "POSITIVE"), 
     |   (((x :Int) => x < 0) -> "NEGATIVE"), 
     |   (((x :Int) => x % 2 == 0) -> "EVEN") 
     |  ) 

res4: Seq[java.lang.String] = ArrayBuffer(POSITIVE, EVEN) 

Hoặc, ít lộn xộn:

scala> multimatch(2, 
    |   ((x :Int) => x > 0 , "POSITIVE"), 
    |   ((x :Int) => x < 0, "NEGATIVE"), 
    |   ((x :Int) => x % 2 == 0, "EVEN") 
    |  ) 
res5: Seq[java.lang.String] = ArrayBuffer(POSITIVE, EVEN) 
Các vấn đề liên quan