解析CSV并在Scala中仅将匹配行添加到功能列表中

解析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

我正在读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
        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
  }