tags:

views:

126

answers:

4

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"                                                      
 | 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.

+8  A: 

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.

Arjan Blokzijl
Thank you... feels like a lame question now. I just realized that for always returns Unit.
Vonn
By the way, for does not always return Unit. If a yield is used, then it can return any of the monad classes (List, Map, Set, Option, ...)
Alex Boisvert
+3  A: 

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).

Rex Kerr
+1  A: 
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")
}
Daniel
A: 

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

user unknown