How do I change this code to be functional programming in scala? - scala

I'm new to functional programming and as I'm reading this book. It basically says that if you code contains "var" it means that you're still doing in a imperative way. I'm not sure how do I change my code to be functional way. Please suggests.
So basically what this code does is to processText some text and use regular expression to extract a particular text from "taggedText" and add that to a list and convert the list to json.
val text = params("text")
val pattern = """(\w+)/ORGANIZATION""".r
var list = List[String]()
val taggedText = processText(text)
pattern.findAllIn(taggedText).matchData foreach {
m => list ::= m.group(1)
}
pretty(render(list)) // render to json

Try replacing the middle section with
val list = pattern.findAllIn(taggedText).matchData.map(m => m.group(1)).toList
You can write m => m.group(1) as _.group(1) if you want.

Related

if statement inside for loop scala

I'm new to scala and I'm trying to learn it. I'm stuck with an very simple thing which I cannot figure out. I simply want, inside a for loop, to check if the current item is present in a map then use that value, otherwise calculate it with a function.
It should be preatty easy but coming from python I cannot understand where the mistake is.
val predictions = for (review <- testValuesAsList;
if (storage.contains("review")){prediction = mymap("review")}
else {prediction = computeItemAvgRat(review._2, trainValuesAsList)}
) yield (review._3, prediction)
return predictions
There are no for loops in Scala, only for comprehensions; they are just sugar syntax for map, flatMap and withFilter calls.
And that is what is making your code fail.
IMHO, the for syntax is rarely better than just calling the combinators explicitly.
val predictions = testValuesAsList.map {
case (_, b, c) => // I don't know what would be proper names for the variables.
val prediction = myMap.getOrElse(
key = "review",
default = computeItemAvgRat(b, trainValuesAsList)
)
c -> prediction
}

How to implement chain of string.replaceAll in Scala

I have a string that I need transform to "canonical" view and for do that I need to call replaceAll() many times on string. I made it work next way:
val text = "Java Scala Fother Python JS C# Child"
val replacePatterns = List("Java", "Scala", "Python", "JS", "C#")
var replaced = text
for (pattern <- replacePatterns) {
replaced = replaced.replaceAll(pattern, "")
}
This code is result in replaced = "Fother Child" as I want, but it looks very imperative and I want eliminate accumulator "replaced".
Is there a way in Scala to handle it in one line without var's?
Thanks.
Use a fold over the list of patterns and the text to be processed as start point:
replacePatterns.foldLeft(text){case (res, pattern) => res.replaceAll(pattern, "")}

Understanding the val declaration syntax for type Some in scala

While going through Spray.io examples library I came across this declaration of val in FileUploadHandler example of routing app.
val Some(HttpHeaders.Content-Type(ContentType(multipart: MultipartMediaType, _))) = header[HttpHeaders.Content-Type]
As per my understanding the variable declaration goes as val <identifier> = ...
Please help in understanding this paradigm of syntax.
val is a bit more complex than just an assignment operator.
A definition
val p = e
where p is not just a variable name, is expanded to
val x = e match { case p => x }
Take a loot at the simplest example:
val Some(s) = Some(5)
As a result, s would be equal 5.
In your example header[HttpHeaders.Content-Type] is matched against Some(...).
According to Scala language spec: Value definitions can alternatively have a pattern as left-hand side. Watch out for PatDef in the document.
Section "Patterns in Value Definitions" of Daniel Westheide's Blog gives a nice overview on the usage.
You're looking for extractors/mattern matching in scala, please see http://www.scala-lang.org/old/node/112.
You need a simple form of it, take a look at this snippet:
scala> val Some(t) = Some("Hello")
t: String = Hello

Scala list find and substraction

my scala list as below `enter code here
List((192.168.11.3,A,1413876302036,-,-,UP,,0.0,0.0,12,0,0,Null0,UP,0,0,4294967295,other), (192.168.11.3,A,1413876302036,-,-,UP,,0.0,0.0,8,0,0,C,DOWN,0,0,100000000,P), (192.168.1.1,A,1413876001775,-,-,UP,,0.0,0.0,12,0,0,E,UP,0,0,4294967295,other), (192.168.1.1,A,1413876001775,-,-,UP,,0.0,0.0,8,0,0,F,DOWN,0,0,100000000,E))
Now I want following operation, in list third parameter are changed in above is 1413876302036 and 1413876001775. I want to subtracts this as below
val sub = ((192.168.11.3,A,(1413876302036-1413876001775),-,-,UP,,0.0,0.0,12,0,0,Null0,UP,0,0,4294967295,other),(192.168.1.1,A,(1413876001775-1413876001775),-,-,UP,,0.0,0.0,12,0,0,E,UP,0,0,4294967295,other))
how should this calculate in scala
After 15 minutes of reading your question, I think I still don't understand it, but if I do here is an answer:
val list = List(("192.168.11.3",'A',1413876302036l,0,0,0), ("192.168.11.3",'A',1413876302036l,0,0,0),
("192.168.1.1",'A',1413876001775l,0,0,0), ("192.168.1.1",'A',1413876001775l,0,0,0))
val newList = list map { _ match {
case (a,b,value,c,d,e) => (a,b,value-1413876001775l,c,d,e)
}}
I allowed myself to rewrite your example a little. Next time try to keep it simple and go with SSCCE rules

Scala Parser Combinator to match element from list

I want a parser that matches if and only if the parsed String is contained by a given list of Strings.
def box: Parser[String] = // match if token is element of boxSyms: List[String]
Even after hours of searching the web, I have no idea how to achieve this. (Which makes me think I've looked for it the wrong way).
Edit:
This is only a snippet from a bigger parser. The input is going to be used in further parser combinators:
lazy val boxModal = box ~ formula ^^ {
case boxSym ~ formula => Box(boxSyms.get(boxSym).get, formula)
}
The problem is that the List boxSyms is unknown at compile time.
Maybe something like this would work:
lazy val boxModal = box ~ formula ^^ {
case boxSym ~ formula if boxSyms.contains(boxSym) =>
Box(boxSyms.get(boxSym).get, formula)
}
Or some other, more specific condition.