2010-04-08 41 views

Trả lời

7

Trong 2.8, bạn có thể muốn sử dụng phương pháp:

scala> val a = "ABCDEF".toList.map(_.toString) 
a: List[java.lang.String] = List(A, B, C, D, E, F) 

scala> a.grouped(2).partialMap{ case List(a,b) => (a,b) }.toList 
res0: List[(java.lang.String, java.lang.String)] = List((A,B), (C,D), (E,F)) 

(Đây là 2.8.0 Beta1; thân mới nhất có collect thay cho partialMap.)

Trong 2,7 - và không phải là một xấu Á hậu trong 2.8 - bạn có thể tạo ra một phương pháp đệ quy như legoscia đã làm:

def zipPairs[A](la : List[A]): List[(A,A)] = la match { 
    case a :: b :: rest => (a,b) :: zipPairs(rest) 
    case _ => Nil 
} 

scala> zipPairs(a) 
res1: List[(java.lang.String, java.lang.String)] = List((A,B), (C,D), (E,F)) 

Edit: đây là một cách tiếp cận ngắn hơn hoạt động trên 2,7 cũng:

scala> (a zip a.drop(1)).zipWithIndex.filter(_._2 % 2 == 0).map(_._1) 
res2: List[(java.lang.String, java.lang.String)] = List((A,B), (C,D), (E,F)) 

(Lưu ý việc sử dụng drop(1) thay vì tail để nó hoạt động với danh sách rỗng.)

4

chưa được kiểm tra:

def ziptwo(l: List[String]): List[(String, String)] = l match { 
    case Nil => Nil 
    case a :: b :: rest => 
     Pair(a,b) :: ziptwo(rest) 
} 
+2

này sẽ không làm việc cho các danh sách miễn là nó không phải là đệ quy đuôi. –

4

trong Scala 2.8 bạn có thể làm:

def pairs[T](xs: List[T]) = 
    xs.grouped(2) 
    .map{case List(a, b) => (a,b)} 
    .toList 
+0

Shucks, đánh bại tôi sau 34 giây! :) Tuy nhiên, bạn muốn 'partialMap' /' collect', hoặc nó sẽ ném một ngoại lệ vào các danh sách dài lẻ. –

+3

Bạn có thể gọi đó là lỗi hoặc tính năng :-) –

1
def pairify[T](list: List[T]): List[(T, T)] = list match { 
    case Nil => Nil 
    case x :: y :: xs => (x, y) :: pairify(xs) 
    case _ => error("odd length list!") 
} 
3

Ưu điểm duy nhất của h aving tất cả mọi người đến với những cách rõ ràng nhất để làm điều đó là tôi phải suy nghĩ nhiều hơn về các giải pháp thay thế. Vì vậy, đây là một trong đó hoạt động trên Scala 2,8. Trên Scala 2.7, thay thế view bằng projection.

def everyNofM[T](l: List[T], n: Int, m: Int) = 
    l.view.zipWithIndex.filter(_._2 % m == n).map(_._1) 
def evens[T](l: List[T]) = everyNofM(l, 0, 2) 
def odds[T](l: List[T]) = everyNofM(l, 1, 2) 
def zip[T](l: List[T]) = evens(l) zip odds(l) toList 

Nói đúng ra, view/projection là không cần thiết, nhưng nó tránh được sự sáng tạo không cần thiết của kết quả trung gian.

cách thú vị khác để làm việc đó:

def zip[T](l: List[T]) = l.indices.partition(_ % 2 == 0).zipped.map(
    (x: Int, y: Int) => (l(x), l(y)) 
).toList 

def zip[T](l: List[T]) = l.zipWithIndex.partition(_._2 % 2 == 0).zipped.map(
    (x, y) => (x._1, y._1) 
) 

PS: Bonus điểm để bất cứ ai nhận được chơi chữ. ;-)

+1

+1, đúng không? [15-char phụ] – missingfaktor

1

này cho phép cặp không đầy đủ:

def pairwise [T] (xs: List[T]) : List [(Option[T], Option[T])] = xs match { 
    case (x :: y :: xsr) => (Some (x), Some (y)) :: pairwise (xsr)    
    case (x :: Nil) => List ((Some (x), None))         
    case (_) => Nil } 
+1

Tôi nghĩ rằng một 'Cặp' của' Tùy chọn' là một lựa chọn tồi. Làm thế nào về một danh sách [[Cặp [T, T], Tuple1 [T]]] 'thay thế? –

+0

Tại sao một cặp Tùy chọn là lựa chọn không hợp lệ? Bởi vì bạn có thể nhận được một cặp Nones? Vâng, điều đó không đẹp, nhưng bạn giữ thông tin ở đó một phần tử đến từ: [mã] Danh sách ((Alicia, New Mexico), (Stefan, Berlin), (Paris)) // Paris Hilton hoặc Paris/Pháp? Danh sách ((Alicia, New Mexico), (Stefan, Berlin), (Không, Paris)) Danh sách ((Alicia, New Mexico), (Stefan, Berlin), (Paris, Không)) [/ code] Trong ví dụ thứ hai, không có thông tin nào bị mất. –

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