tags:

views:

81

answers:

4

For example, from a following file:

Name,Surname,E-mail
John,Smith,[email protected]
Nancy,Smith,[email protected]
Jane,Doe,[email protected]
John,Doe,[email protected]

how do I get e-mail address of John Doe?

I use the following code now, but can specify only one key field now:


val src = Source.fromFile(file)
val iter = src.getLines().drop(1).map(_.split(","))
var quote = ""
iter.find( _(1) == "Doe"  ) foreach (a => println(a(2)))
src.close()

I've tried writing "iter.find( _(0) == "John" && _(1) == "Doe" )", but this raises an error saying that only one parameter is expected (enclosing the condition into extra pair of parentheses does not help).

+5  A: 

The underscore as a placeholder for a parameter to a lambda doesn't work the way that you think.

a => println(a)
// is equivalent to
println(_)

(a,b) => a + b
// is equivalent to 
_ + _

a => a + a
// is not equivalent to
_ + _

That is, the first underscore means the first parameter and the second one means the second parameter and so on. So that's the reason for the error that you're seeing -- you're using two underscores but have only one parameter. The fix is to use the explicit version:

iter.find( a=> a(0) == "John" && a(1) == "Doe" )
dpp
A: 

Have you tried doing a pattern matching with a regular expression:

johnDoe = """(John)/w*,/w*(Doe),.*""".r

def parseLine( _input:String ) = _input match{
    case johnDoe( john, doe ) => println( john + doe )
    case _ => Unit
}

Where you're taking advantage of the ability of Scala to use regular expressions in pattern matching. Technically, if you really wanted, you could parse the whole file like this by pulling out all the names, surnames, and email addresses.

wheaties
+1  A: 

You can use Regex:

scala> def getRegex(v1: String, v2: String) = (v1 + "," + v2 +",(\\S+)").r
getRegex: (v1: String,v2: String)scala.util.matching.Regex

scala> val src = """John,Smith,[email protected]
     | Nancy,Smith,[email protected]
     | Jane,Doe,[email protected]
     | John,Doe,[email protected]
     | """
src: java.lang.String =
John,Smith,[email protected]
Nancy,Smith,[email protected]
Jane,Doe,[email protected]
John,Doe,[email protected]


scala> val MAIL = getRegex("John","Doe")
MAIL: scala.util.matching.Regex = John,Doe,(\S+)

scala> val itr = src.lines
itr: Iterator[String] = non-empty iterator

scala> for(MAIL(address) <- itr) println(address)
[email protected]

scala>
Eastsun
And you can also use MAIL.findAllIn(src).
Eastsun
A: 

You could also do a pattern match on the result of split in a for comprehension.

val firstName = "John"
val surName = "Doe"
val emails = for {
  Array(`firstName`, `surName`, email) <- 
    src.getLines().drop(1) map { _ split ',' }
} yield { email }

println(emails.mkString(","))

Note the backticks in the pattern: this means we match on the value of firstName instead of introducing a new variable matching anything and shadowing the val firstname.

mkneissl