Reputation: 509
I want to convert a string to list with comma separator but with condition if i have a specific word after comma.
this is my input string:
val x = "StructField(AverageOverallRating1,DoubleType,true),StructType(AverageOverallRating2,DoubleType,true),ArrayType(AverageOverallRating3,DoubleType,true),StructType(StructField(AverageOverallRating1,DoubleType,true),StructField(AverageOverallRating1,DoubleType,true))"
I want to get a result like this :
StructField(AverageOverallRating1,DoubleType,true)
StructType(AverageOverallRating2,DoubleType,true)
ArrayType(AverageOverallRating3,DoubleType,true)
StructType(StructField(AverageOverallRating1,DoubleType,true),StructField(AverageOverallRating1,DoubleType,true))
I tried to split(",") but it doesn't work, I think the solution is with regex but I can't find the right expression
Upvotes: 0
Views: 125
Reputation: 27535
If I were to parse that thing I would use type - and once I would get ADT with some reasonable representation I would decide how to handle it. For instance with fastparse 2 I would try to implement it somehow like this:
import fastparse._, NoWhitespace._
def boolean[_: P]: P[Boolean] = P( "true" | "false" ).map(_.toBoolean)
// assuming that there is a type DoubleType
sealed trait DoubleType
objecy DoubleType extends DoubleType
def doubleType[_ : P]: P[DoubleType] = P( "DoubleType" ).map(_ => DoubleType)
// assuming there is an enum AverageOverallRating with withName method
sealed trait AverageOverallRating
object AverageOverallRating {
case object AverageOverallRating1 extends AverageOverallRating
case object AverageOverallRating2 extends AverageOverallRating
case object AverageOverallRating3 extends AverageOverallRating
def withName(string: String): AverageOverallRating = ???
}
def averageOverallRating: P( "AverageOverallRating1" | "AverageOverallRating2" | "AverageOverallRating3" ).map(AverageOverallRating.withName)
sealed trait Entry
case class StructField(averageOverallRating: averageOverallRating, doubleType: DoubleType, boolean: Boolean) extends Entry
case class StructType(averageOverallRating: averageOverallRating, doubleType: DoubleType, boolean: Boolean) extends Entry
case class ArrayType(averageOverallRating: averageOverallRating, doubleType: DoubleType, boolean: Boolean) extends Entry
def structField[_ : P]: P[StructField] = P( "StructField" ~ "(" ~ averageOverallRating ~ "," ~ doubleType ~ "," ~ boolean ~ ")").map {
case (_, _, a, _, b, _, c, _) => StructField(a, b, c)
}
def structType[_ : P]: P[StructType] = P( "StructType" ~ "(" ~ averageOverallRating ~ "," ~ doubleType ~ "," ~ boolean ~ ")").map {
case (_, _, a, _, b, _, c, _) => StructField(a, b, c)
}
def arrayType[_ : P]: P[ArrayType] = P( "ArrayType" ~ "(" ~ averageOverallRating ~ "," ~ doubleType ~ "," ~ boolean ~ ")").map {
case (_, _, a, _, b, _, c, _) => StructField(a, b, c)
}
def entry[_ : P]: P[Entry] = P(structField | structType | arrayType)
def entries[_ : P]: P[List[Entry]] = P( entry ~ ("," ~ entry).rep ).map { case (head, tail) =>
head +: tail.toList.map(_._2)
}
val input = "StructField(AverageOverallRating1,DoubleType,true),StructType(AverageOverallRating2,DoubleType,true),ArrayType(AverageOverallRating3,DoubleType,true),StructType(StructField(AverageOverallRating1,DoubleType,true),StructField(AverageOverallRating1,DoubleType,true))"
val result = parse(input, entries(_))
(Disclaimer: this is just a quickly written draft/example/pseudocode, I don't expect it to compile and work immediately).
Once I would get result
and made sure it is correct, I would just use the List[Entry]
to produce the final result much, much easier, e.g.
entries.map(_.toString).mkString("\n")
Upvotes: 1