2011-11-28 31 views
6

Làm thế nào bạn sẽ viết một thực hiện funcitonal cho split(positions:List[Int], str:String):List[String], mà là tương tự như splitAt nhưng chia tách một chuỗi cho trước thành một danh sách của dây bằng một danh sách cho các vị trí ?Làm thế nào để tách một chuỗi cung cấp một danh sách các vị trí trong Scala

Ví dụ

  • split(List(1, 2), "abc") lợi nhuận List("a", "b", "c")
  • split(List(1), "abc") lợi nhuận List("a", "bc")
  • split(List(), "abc") lợi nhuận List("abc")
+1

Tôi muốn sử dụng một giải pháp dựa trên 'chuỗi con 'thay vì' splitAt'. Trước đây sẽ sử dụng lại 'String' ban đầu trong bộ nhớ, trong khi thứ hai sẽ sao chép các chuỗi thành các chuỗi mới. Các giải pháp được cung cấp có thể được điều chỉnh để sử dụng 'chuỗi con'. –

Trả lời

4
def lsplit(pos: List[Int], str: String): List[String] = { 
    val (rest, result) = pos.foldRight((str, List[String]())) { 
    case (curr, (s, res)) => 
     val (rest, split) = s.splitAt(curr) 
     (rest, split :: res) 
    } 
    rest :: result 
} 
4

Something như thế này:

def lsplit(pos: List[Int], s: String): List[String] = pos match { 
    case x :: rest => s.substring(0,x) :: lsplit(rest.map(_ - x), s.substring(x)) 
    case Nil => List(s) 
} 

(Cảnh báo công bằng: không phải đệ quy đuôi, do đó sẽ thổi xếp chồng cho các danh sách lớn; không hiệu quả do lặp lại các chỉ số và chuỗi các bản chất lặp đi lặp lại. Bạn có thể giải quyết những điều này bằng cách thêm tham số bổ sung và/hoặc một phương pháp nội bộ mà không được đệ quy.)

+0

Cảm ơn. Tôi sẽ làm cho một phiên bản đệ quy đuôi của giải pháp của bạn. – Michael

+2

@Michael - Có thể cũng muốn xem xét việc thêm chỉ mục 'startAt' để bạn có thể' s.substring (startAt, x) :: lsplit (phần còn lại, s, startAt + x) '(trong phiên bản không đệ quy đuôi, tất nhiên). Nếu bạn làm thế, đừng quên trường hợp 'Nil'. –

2

Làm thế nào về ....

def lSplit(indices : List[Int], s : String) = (indices zip (indices.tail)) map { case (a,b) => s.substring(a,b) } 

scala> lSplit(List(0,4,6,8), "20131103") 
List[String] = List(2013, 11, 03) 
Các vấn đề liên quan