I am quite new to Scala and functional programming. I wrote the simple codes as below, which manipulates the string by counting the word. When the 4th comma-delimitted part is empty then, I concated only three columns, otherwise I concated all the columns including the values as code above.
But I think that it is not quite proper to the functional programming. Because I used the if statement to see the input value contains the value or not.
How to change it to the more scala-like code?
str = "aa,bb,1668268540040,34.0::aa,bb,1668268540040"
val parts = str.split("::")
for (case <- parts) {
val ret = case.map(c => if (c.value.isEmpty) {
c.columnFamily "," c.qualifier "," c.ts
} else {
c.columnFamily "," c.qualifier "," c.ts "," c.value
})
}
str = "aa,bb,1668268540040,34.0::aa,bb,166826434343"
val parts = str.split("::")
for (part <- parts) {
val elem = part.split(",", 4)
if (elem.length == 4) {
val Array(f, q, t, v) = elem
state.put(f ":" q, (v, t.toLong))
} else {
val Array(f, q, t) = elem
state.put(f ":" q, ("", t.toLong))
}
}
CodePudding user response:
@LeviRamsey's comment tells you actually everything, but just to make your code more "scala-ish", you should avoid mutable data structures in the first place (what you're doing with state, which I think is a Map object), and use immutable data structures. About your if-else
part, it's actually okay in FP, but in Scala, you can use pattern matching on a list, rather than manual length checking and using Arrays
. Something like this:
parts.foldLeft(Map.empty[String, (String, Long)]) {
case (state, part) =>
part.split(",", 4).toList match {
case f :: q :: t :: v :: Nil =>
state.updated(f ":" q, (v, t.toLong))
case f :: q :: t :: Nil =>
state.updated(f ":" q, ("", t.toLong))
case _ => state // or whatever thing you want to do, in case neither 4 nor 3 elements are splitted
}
}