How do I return a String from a for comprehension in Scala?
Scala Newbie alert:
basically I'm trying to do something like this: where I pattern match and return a String.
scala> def processList(list: List[String], m: String): String={list foreach (x=> m match{
| case "test" => "we got test"
开发者_如何学Go | case "test1"=> "we got test1"})}
:10: error: type mismatch; found : Unit required: String def processList(list: List[String], m: String): String={list foreach (x=> m match{
I know I can set a var and return it after the for comp... but that doesn't seem to be the Scala way.
It is not completely clear to me what exactly it is that you are trying to do. Do you just want to test whether a certain element is present in the list? Or do you want to return a list of strings with some transformation? The latter, for example, can be written like so:
scala> def processList(l: List[String]): List[String] = l map {s => s match {
case "test" => "we got test"
case "test1" => "we got test1"
case _ => "we got something else"
}
}
scala> processList(List("test", "test1", "test2", "test3"))
res: List[String] = List(we got test, we got test1, we got something else, we got something else)
And for the former you could write something like:
scala> def exists(l: List[String], m: String): String = {
if (l exists (s => s == m))
m + " exists"
else
m + " does not exist"
}
exists: (l: List[String],m: String)String
scala> val l = List("test1", "test2", "test3")
l: List[java.lang.String] = List(test1, test2, test3)
scala> exists(l, "test1")
res0: String = test1 exists
scala> exists(l, "test2")
res1: String = test2 exists
scala> exists(l, "test8")
res2: String = test8 does not exist
In any case: the foreach method on a List loops over every element in a list, applying the given function to each element. It is mainly used for side-effecting, such as printing something to the console, or writing to a file. The function passed to the foreach method,must return the Unit type, which is like void in Java. You cannot return a single String from it, therefore.
You need to use map
, not foreach
. And then you can either return the list of strings (just as you've written, except the return type is List[String]
) or you can stick them together using .mkString(" ")
(that will put spaces between them).
def processList(list: List[String], m: String): String= {
list foreach (x=> m match {
case "test" => return "we got test"
case "test1"=> return "we got test1"
})
error("oops")
}
To return a single result on the fly - maybe by concatenating the single results, you may use (INIT /: COLLECTION) (_ OPERATION _) like this:
val li = List ("test", "test", "test1", "test")
("" /: li) ((x, y) => x + { y match {
case "test" => "we got test\n"
case "test1" => "we got test 1\n" } } )
res74: java.lang.String = we got test we got test we got test 1 we got test
精彩评论