В Scala, как найти элемент в CSV по паре ключевых значений? - PullRequest
5 голосов
/ 03 сентября 2010

Например, из следующего файла:

Name,Surname,E-mail
John,Smith,john.smith@hotmail.com
Nancy,Smith,nancy.smith@gmail.com
Jane,Doe,jane.doe@aol.com
John,Doe,john.doe@yahoo.com

как мне получить адрес электронной почты Джона Доу?

Сейчас я использую следующий код, но могу указать только одно ключевое поле:


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

Я пытался написать "iter.find (_ (0) ==" Джон "&& _ (1) ==" Доу ")", но возникает ошибка, сообщающая, что ожидается только один параметр (включающий условие в лишнюю пару скобок не помогает).

Ответы [ 3 ]

5 голосов
/ 03 сентября 2010

Подчеркивание в качестве заполнителя для параметра лямбда не работает так, как вы думаете.

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

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

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

То есть первое подчеркивание означает первый параметр, а второе означает второй параметр и так далее. Вот причина ошибки, которую вы видите - вы используете два подчеркивания, но имеете только один параметр. Исправление заключается в использовании явной версии:

iter.find( a=> a(0) == "John" && a(1) == "Doe" )
1 голос
/ 03 сентября 2010

Вы можете использовать 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,john.smith@hotmail.com
     | Nancy,Smith,nancy.smith@gmail.com
     | Jane,Doe,jane.doe@aol.com
     | John,Doe,john.doe@yahoo.com
     | """
src: java.lang.String =
John,Smith,john.smith@hotmail.com
Nancy,Smith,nancy.smith@gmail.com
Jane,Doe,jane.doe@aol.com
John,Doe,john.doe@yahoo.com


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)
john.doe@yahoo.com

scala>
0 голосов
/ 03 сентября 2010

Вы также можете выполнить сопоставление с шаблоном по результату split в понимании for.

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

println(emails.mkString(","))

Обратите внимание на обратные помехи в шаблоне: это означает, что мы сопоставляем значение firstName вместо того, чтобы вводить новую переменную, совпадающую с чем-либо, и затенять val firstname.

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...