2013-02-20 29 views
7

Tôi muốn chia một chuỗi trên khoảng trắng có 4 yếu tố:Scala chia chuỗi tuple

1 1 4.57 0.83 

và tôi đang cố gắng để chuyển đổi thành Danh sách [(String, String, Point)] đến nỗi hai đầu chia tách là hai phần tử đầu tiên trong danh sách và hai phần tử cuối cùng là Điểm. Tôi làm như sau nhưng nó dường như không làm việc:

Source.fromFile(filename).getLines.map(string => { 
      val split = string.split(" ") 
      (split(0), split(1), split(2)) 
     }).map{t => List(t._1, t._2, t._3)}.toIterator 
+1

Nếu bạn muốn một tuple tại sao bạn lại nói rằng bạn muốn chuyển đổi thành Danh sách? –

+0

Tôi đồng ý, điều này có thể sẽ được đặt tên gần hơn để chuyển đổi chuỗi thành Danh sách() của các thành phần –

Trả lời

8

Bạn có thể sử dụng mô hình phù hợp để trích xuất những gì bạn cần từ mảng:

case class Point(pts: Seq[Double]) 
    val lines = List("1 1 4.34 2.34") 

    val coords = lines.collect(_.split("\\s+") match { 
     case Array(s1, s2, points @ _*) => (s1, s2, Point(points.map(_.toDouble))) 
    }) 
+1

Điều này không biên dịch cho tôi, tôi đã thêm một câu trả lời tương tự khác để biên dịch - Tôi không thể lấy mã để hiển thị đúng trong nhận xét. Tôi sẽ tò mò muốn xem cách thu thập có thể được sử dụng nếu ai đó biết. –

+0

từ API của 'collect' *" Xây dựng một bộ sưu tập mới bằng cách áp dụng một phần chức năng cho tất cả các yếu tố của danh sách này mà trên đó hàm được xác định. "*. Nó giống như 'map' nhưng chỉ để lại các phần tử trong miền của hàm partial –

1

Bạn chưa chuyển đổi các thẻ thứ ba và thứ tư vào một Point, cũng không phải bạn đang chuyển đổi dòng thành một List. Ngoài ra, bạn không hiển thị từng phần tử dưới dạng Tuple3, nhưng dưới dạng List.

Sau đây phải phù hợp hơn với những gì bạn đang tìm kiếm.

case class Point(x: Double, y: Double) // Simple point class 
Source.fromFile(filename).getLines.map(line => { 
    val tokens = line.split("""\s+""") // Use a regex to avoid empty tokens 
    (tokens(0), tokens(1), Point(tokens(2).toDouble, tokens(3).toDouble)) 
}).toList // Convert from an Iterator to List 
+0

PS: Tôi đã không kiểm tra điều này. – cheeken

+0

Lớp điểm của tôi mất (IndexedSeq [Double]) vậy làm thế nào để tôi lấy Indexq Seq từ tuple? –

13

Làm thế nào về điều này:

scala> case class Point(x: Double, y: Double) 
defined class Point 

scala> s43.split("\\s+") match { case Array(i, j, x, y) => (i.toInt, j.toInt, Point(x.toDouble, y.toDouble)) } 
res00: (Int, Int, Point) = (1,1,Point(4.57,0.83)) 
+0

Đơn giản và rõ ràng. Bạn có thể muốn thêm một trường hợp để xử lý lỗi đầu vào. –

-1

Có nhiều cách để chuyển đổi một tuple vào danh sách hoặc Seq , Một chiều là

scala> (1,2,3).productIterator.toList 
res12: List[Any] = List(1, 2, 3) 

Bu t như bạn có thể thấy rằng các kiểu trả về là Bất kỳ và KHÔNG một INTEGER

Để chuyển đổi thành các loại khác nhau mà bạn sử dụng Hlist của https://github.com/milessabin/shapeless

1
case class Point(pts: Seq[Double]) 
val lines = "1 1 4.34 2.34" 

val splitLines = lines.split("\\s+") match { 
    case Array(s1, s2, points @ _*) => (s1, s2, Point(points.map(_.toDouble))) 
} 

Và đối với những tò mò, các @ trong mô hình khớp nối liên kết một biến với mẫu, do đó, points @ _* ràng buộc các điểm biến với mẫu * _ và * _ khớp với phần còn lại của mảng, do đó các điểm kết thúc bằng một chuỗi Seq [String].

+0

Hm .. Tôi nhận được scala.MatchError: [Ljava.lang.String; @ 7bfacd5d (của lớp [Ljava.lang.String;) Tôi làm gì sai? – Sergey