2016-12-03 162 views
-1

有表示爲一個字符串如下:斯卡拉解析/分割字符串

val str = "teacher.name:ABC DEF student.age:20 teacher.gender:male teacher.tag:123 student.name:XYZ" 

我想組由教師和學生,這樣的結果將是:

val teacher = "name:ABC DEF gender:male tag:123" 

val student = "age:20 name:XYZ" 

在這個例子中,要麼是「老師」。或「學生」。是一種有意義的分隔符。假設沒有「。」在其他地方。

如何使用Scala編寫代碼來很好地完成它?

+0

嗯,好,那麼這裏有什麼有意義的分隔符?如果你有「霍華德學生」或「珍妮特蘇泰克」這樣的名字怎麼辦?什麼是保證識別每個記錄開始/結束的標記? – jwvh

+0

在這個例子中,無論是「老師」。或「學生」。是一種有意義的分隔符。假設沒有「。」在其他地方。好問題。 – ttt

回答

2

這可能會做它。

val str = "teacher.name:ABC DEF student.age:20 teacher.gender:male teacher.tag:123 student.name:XYZ" 

val teacher = str.split("teacher.").map(_.split("student.").head.trim).tail.mkString(", ") 
// teacher: String = name:ABC DEF, gender:male, tag:123 

val student = str.split("student.").map(_.split("teacher.").head.trim).tail.mkString(", ") 
// student: String = age:20, name:XYZ 

在冗長的一面位,但一個簡單的算法:分你想要的標籤,子劃分您沒有在標籤上。

+0

看起來如果名稱包含' - ',它將不起作用。 – ttt

+0

我不知道你爲什麼這麼說。你有嘗試過嗎?根據我的測試,在名稱或其他地方有' - ',不會破壞任何東西。 – jwvh

1

「精美」是相對的,它可能只是最好走的字符串,但蠻力答案扶着Scala的收集方法可能:

// tokenize the input 
val tokens = str.reverse.split(':').flatMap(_.split(" ", 2)).map(_.reverse).reverse 

// zip tokens into key-value pairs 
val pairs = (tokens zip tokens.drop(1)).zipWithIndex.filter(_._2 % 2 == 0).map(_._1) 

// group key-value pairs and join string 
pairs.groupBy(_._1.split('.').head).mapValues(_.collect({ case (a, b) => a.split('.').last + ":" + b }).mkString(" ")) 

// Map(student -> age:20 name:XYZ, teacher -> name:ABC DEF gender:male tag:123) 

```