【问题标题】:Filtering maps in iterator在迭代器中过滤映射
【发布时间】:2014-03-05 23:14:31
【问题描述】:

我有以下代码:

val rows: Iterator[Map[String,String]] = CSVDictReader(file.getInputStream)
val parsedProducts = rows.map(x => Product(name = x.get("NAME"), id = x.get("ID")))

我想用空字符串替换地图条目。我可以单独使用地图:

filter(_._2.trim.nonEmpty)

如果不引入一些帮助函数以在值为空字符串的情况下返回 None ,我无法理解如何以一种很好的方式做到这一点。

编辑:在我的示例中,我只有名称和 ID,但在实际代码中,很容易有超过十列​​数据。另外,我需要 None 而不是空字符串值。所以 name=Option("") 应该替换为 name=None

【问题讨论】:

  • 替换还是删除?如果你想替换它们,还有什么可以替代你从地图中获得的空字符串?

标签: scala


【解决方案1】:

您也可以过滤Options。

假设您的x.get("NAME") 返回Some("") 甚至Some(" ")

那么你可以这样做:x.get("NAME").filter(_.trim.nonEmpty)

希望我正确理解了您的问题

【讨论】:

  • 是的,这可行,但我想避免为每个 CSV 字段复制 .filter(_.trim.nonEmpty)。
【解决方案2】:

这样的?

val rows: Iterator[Map[String,String]] = CSVDictReader(file.getInputStream)
val parsedProducts = for {
    row <- rows 
    name <- row.get("NAME")
    id <- row.get("ID")
} yield Product(name, id)

这里,如果row.get("NAME")或者row.get("ID")返回None,对应的条目将不会被产生。

【讨论】:

    【解决方案3】:

    我不确定这是否是您要查找的内容,但以下代码 sn-p:

       val rows: Iterator[Map[String,String]] = Iterator(Map("NAME" -> " ", "ID" -> "foo"), Map("NAME" -> " ", "ID" -> ""))
       val fieldNames = List("NAME","ID","ANOTHER COLUMN")
       val cleanedRows = rows map { row =>
         fieldNames map { fieldName =>
           Map ( fieldName -> row.get(fieldName).filter (_.trim.nonEmpty) )
         }
       }
    
       while(cleanedRows.hasNext) {
         println(cleanedRows.next)
       }
    

    会打印出来:

       List(Map(NAME -> None), Map(ID -> Some(foo)), Map(ANOTHER COLUMN -> None))
       List(Map(NAME -> None), Map(ID -> None), Map(ANOTHER COLUMN -> None))
    

    所以此时cleanedRows 将拥有创建Product 实例所需的条目。

    【讨论】:

      猜你喜欢
      • 2017-12-22
      • 1970-01-01
      • 1970-01-01
      • 2020-04-18
      • 1970-01-01
      • 2016-07-05
      • 2021-04-15
      • 2011-07-31
      • 1970-01-01
      相关资源
      最近更新 更多