2016-12-03 163 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) 

```