2016-12-03 2 views
-1

Существует строка представлена ​​следующим образом:Scala разобрать/разбить строку

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) 

`` `

Смежные вопросы