在Scala中,如何通过一对键值查找CSV中的elemein?

发布于 2024-09-18 05:52:02 字数 1034 浏览 5 评论 0原文

例如,从以下文件中:

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

如何获取 John Doe 的电子邮件地址?

我现在使用以下代码,但现在只能指定一个关键字段:


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) == "John" && _(1) == "Doe" )" ,但这会引发一个错误,指出只需要一个参数(将条件括在额外的一对括号中没有帮助)。

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

如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。

扫码二维码加入Web技术交流群

发布评论

需要 登录 才能够评论, 你可以免费 注册 一个本站的账号。

评论(3

淡写薰衣草的香 2024-09-25 05:52:02

下划线作为 lambda 参数的占位符并不像您想象的那样工作。

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

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" )
做个ˇ局外人 2024-09-25 05:52:02

您可以使用正则表达式:

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>

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>
·深蓝 2024-09-25 05:52:02

您还可以在 for 理解中对 split 的结果进行模式匹配。

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

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.

~没有更多了~
我们使用 Cookies 和其他技术来定制您的体验包括您的登录状态等。通过阅读我们的 隐私政策 了解更多相关信息。 单击 接受 或继续使用网站,即表示您同意使用 Cookies 和您的相关数据。
原文