如何使用foldLeft内联(没有占位符,无需单独定义op方法)

时间:2014-01-23 15:22:19

标签: scala

我正在尝试使用单行代码来获得下面的折叠左侧代码。我一直遇到奇怪的错误阻止我这样做。这是一个捕获问题域本质的片段:

  val contentByName: Map[String, Set[String]] =
    Map(
        ("idsFromDb1" -> Set("1", "2", "3"))
      , ("idsFromDb2" -> Set("2", "3", "6", "7"))
      , ("idsFromDb3" -> Set("4", "5", "6", "9", "10"))
    )
  def foldOp(x: Set[String], y: (String, Set[String])): Set[String] =
    if (y._2.filter(_.size != 1).size == 0) x ++ y._2 else x
  val all0 = contentByName.foldLeft(Set[String]())(foldOp)
  val all1 = contentByName.foldLeft(Set[String]())((x: Set[String], y: (String, Set[String]))) => if (y._2.filter(_.size != 1).size == 0) x ++ y._2 else x)

如果可能的话,我想避免定义方法foldOp(),并且只是内联它。但是,我尝试了各种各样的变化并没有成功。例如,all1行显示以下错误(Scala Worksheet中Eclipse中的ScalaIDE):

  • ';'预期,但')'发现。
  • 未找到:值x
  • 未找到:值x
  • 未找到:值x
  • 不是合法的形式参数

我用google搜索并明确搜索了StackOverflow(我发现很难找到如何搜索这个)。我没有找到任何东西所以,非常感谢任何帮助,包括将其标识为重复并指向我(这可能会让我理解如何在将来更好地搜索)。谢谢。

更新 事实证明,在我all1案例之前=>之前,我有一个额外的括号。我几乎总是在多行上构建这些类型的构造,在这种情况下并不是这样。哎呀。

此外,我从fotNelton那里了解了一种新方法“案例”。所以,这对我来说仍然非常有成效。

1 个答案:

答案 0 :(得分:4)

你可以这样做:

val contentByName: Map[String, Set[String]] =
  Map(
    "idsFromDb1" -> Set("1", "2", "3"),
    "idsFromDb2" -> Set("2", "3", "6", "7"),
    "idsFromDb3" -> Set("4", "5", "6", "9", "10")
  )

contentByName.foldLeft(Set.empty[String]) { case (acc, (key, value)) =>
  if (acc.size == 1) acc else acc ++ value
}

请注意,我正在使用“内联”方法的模式匹配语法(更好地称之为匿名函数),因为这样可以更容易理解折叠。

编辑:同时,OP已经改变了折叠的语义,但这不应该影响这里的方法。