解析CSV并在Scala中仅将匹配行添加到功能列表中
我正在读csv scala。 Person是一个case类解析CSV并在Scala中仅将匹配行添加到功能列表中,scala,functional-programming,pattern-matching,Scala,Functional Programming,Pattern Matching,我正在读csv scala。 Person是一个case类 Case class Person(name, address) def getData(path:String,existingName) : List[Person] = { Source.fromFile(“my_file_path”).getLines.drop(1).map(l => { val data = l.split("|", -1).map(_.trim).toList
Case class Person(name, address)
def getData(path:String,existingName) : List[Person] = {
Source.fromFile(“my_file_path”).getLines.drop(1).map(l => {
val data = l.split("|", -1).map(_.trim).toList
val personName = data(0)
if(personName.equalsIgnoreCase(existingName)) {
val address=data(1)
Person(personName,address)
//here I want to add to list
}
else
Nil
///here return empty list of zero length
}).toList()
}
我想在scala中实现这一功能。以下是我认为您正在尝试的基本方法
case class Person(name:String, address:String)
def getData(path:String, existingName:String) :List[Person] = {
val recordPattern = raw"\s*(?i)($existingName)\s*\|\s*(.*)".r.unanchored
io.Source.fromFile(path).getLines.drop(1).collect {
case recordPattern(name,addr) => Person(name, addr.trim)
}.toList
}
这不会关闭文件读取器,也不会在文件无法打开时报告错误,这是您真正应该做的,但我们会将其留到另一天
更新:使用(Scala 2.13)通过
添加文件关闭和错误处理
更新的更新
嗯。以下是一个版本:
- 如果无法打开文件,则报告错误
- 打开并读取文件后关闭该文件
- 忽略不需要的空格和引号
- pre-2.13编译器友好吗
下面是正则表达式的工作原理:
[\s”]*
可能有空格或引号
(?i)
匹配不区分大小写
($existingName)
匹配并捕获此字符串(第一个捕获组)
[“\s]*
可能有空格或引号
\\\124;
将有一个条形字符
[\s”]*
可能有空格或引号
([^“|]*)
匹配并捕获所有非引号或条形图的内容
*
忽略此后可能发生的任何事情
以下是我认为您正在尝试的基本方法
case class Person(name:String, address:String)
def getData(path:String, existingName:String) :List[Person] = {
val recordPattern = raw"\s*(?i)($existingName)\s*\|\s*(.*)".r.unanchored
io.Source.fromFile(path).getLines.drop(1).collect {
case recordPattern(name,addr) => Person(name, addr.trim)
}.toList
}
这不会关闭文件读取器,也不会在文件无法打开时报告错误,这是您真正应该做的,但我们会将其留到另一天
更新:使用
(Scala 2.13)通过添加文件关闭和错误处理
更新的更新
嗯。以下是一个版本:
- 如果无法打开文件,则报告错误
- 打开并读取文件后关闭该文件
- 忽略不需要的空格和引号
- pre-2.13编译器友好吗
下面是正则表达式的工作原理:
[\s”]*
可能有空格或引号
(?i)
匹配不区分大小写
($existingName)
匹配并捕获此字符串(第一个捕获组)
[“\s]*
可能有空格或引号
\\\124;
将有一个条形字符
[\s”]*
可能有空格或引号
([^“|]*)
匹配并捕获所有非引号或条形图的内容
*
忽略此后可能发生的任何事情
你不太清楚你的方法有什么问题,但这应该可以解决问题(非常接近你的问题)
我们每行读取一行文件,每行从第一个csv字段中提取personName,如果它是我们要查找的,则返回一个(Option)Person,否则返回一个(Option.empty)。通过使用flatmap,我们放弃了空选项(只是为了避免使用nils)您不太清楚在您的方法中出现了什么问题,但这应该可以解决问题(非常接近您的问题)
我们每行读取一行文件,每行从第一个csv字段中提取personName,如果它是我们要查找的,则返回一个(Option)Person,否则返回一个(Option.empty)。通过使用flatmap,我们放弃了空选项(只是为了避免使用nils)在同时进行不区分大小写的比较时,一种干净有效的方法来提取名称
和地址
。还请建议如何关闭io conn.regex未获得编译这是一个与IDE相关的错误..找不到声明..请解释regex.i我的csv字符串在双引号中我是通过replaceall删除它们。。。。。示例:-“SomeName”|“SomeAddress”|…将来我可能会更详细。一种干净有效的方法,在同时进行不区分大小写的比较时提取名称
和地址
。另外,请建议如何关闭io conn.regex未获得编译。这是一个与IDE相关的错误。找不到声明。请解释regex.i我的csv字符串在双引号中,我将通过replaceall删除它们。。。。。示例:-“SomeName”|“SomeAddress”|..将来我可能会更喜欢col.Ok..选项有效..你能建议我阅读后如何关闭连接吗?更新答案。但是请你自己寻找。。。如果你google scala Source close,这应该是第一个结果…是的,得到了…我在scala中寻找与finally block等效的东西。我问得不对。谢谢你的回答。在java中,你已经尝试了资源。在scala中,我不认为有什么是等价的。您可以创建一个高阶函数来接收源和块。它将执行块并在最后关闭源。基本上是用资源复制java try。请参阅“在Scala中尝试使用资源”部分我将以列表的形式获得输出(无,无,…)…我希望其长度为零。好的..使用选项它正在工作..您可以建议我在阅读后如何关闭连接。更新了答案。但是请你自己寻找。。。如果你google scala Source close,这应该是第一个结果…是的,得到了…我在scala中寻找与finally block等效的东西。我问得不对。谢谢你的回答。在java中,你已经尝试了资源。在scala中,我不认为有什么是等价的。您可以创建一个高阶函数来接收源和块。它将执行块并在最后关闭源。基本上是用资源复制java try。请参见“在Scala中尝试使用资源”一节,我将以列表的形式获得输出(无,无,…)…我希望它的长度为零。
import scala.util.Try
case class Person(name:String, address:String)
def getData(path:String, existingName:String) :List[Person] = {
val recordPattern =
raw"""[\s"]*(?i)($existingName)["\s]*\|[\s"]*([^"|]*)*.""".r
val file = Try(io.Source.fromFile(path))
val res = file.fold(
err => {println(err); List.empty[Person]},
_.getLines.drop(1).collect {
case recordPattern(name,addr) => Person(name, addr.trim)
}.toList)
file.map(_.close)
res
}
def getData(path:String, existingName: String) : List[Person] = {
val source = Source.fromFile("my_file_path")
val lst = source.getLines.drop(1).flatMap(l => {
val data = l.split("|", -1).map(_.trim).toList
val personName = data.head
if (personName.equalsIgnoreCase(existingName)) {
val address = data(1)
Option(Person(personName, address))
}
else
Option.empty
}).toList
source.close()
lst
}