Scala 需要一个指南来调整这个嵌套for循环的功能吗

Scala 需要一个指南来调整这个嵌套for循环的功能吗,scala,functional-programming,Scala,Functional Programming,我正在处理这个scala代码: case class M(a: String, b: Int) val mm1 = List(Map("a" -> "001", "b" -> 12), Map("a" -> "002", "b" -> 25), Map("a" -> "003", "b" -> 100)) val mm2 = List(M("001", 12), M("004", 99), M("003", 100)) def valida

我正在处理这个scala代码:

  case class M(a: String, b: Int)

  val mm1 = List(Map("a" -> "001", "b" -> 12), Map("a" -> "002", "b" -> 25), Map("a" -> "003", "b" -> 100))
  val mm2 = List(M("001", 12), M("004", 99), M("003", 100))

  def validate(mm1: List[Map[String, Any]], mm2: List[M]): Boolean = {

    for (m1 <- mm1) {
      var found = false
      val a = m1("a")

      // nested loop: iterate mm2
      breakable {
        for (m2 <- mm2) {
          if (a == m2.a) {
            assert(m1("b") == m2.b)
            found = true
            break  // if found just break
          }
        }
      }

      // All of elements in mm1 must exist in mm2.
      // We will know this if "found" variable is set to true.
      assert(found == true)
    }
    true
  }
不是很好,因为我无法将
var found=false
放入。所以我无法检查mm1中的所有项目是否都存在于mm2中


任何人都可以提供帮助或有更好的想法(可能使用递归或根本不使用
var-found

考虑类似的事情,也许:

val ms = mm2.map(m => m.a -> m.b).toMap
mm1.foreach { m => 
    assert(m.get(a).flatMap(ms.get).exists(_ == m("b")))
}

true

(在我看来)可以使用
for all
(它接受一个谓词,如果集合中的所有元素都满足该谓词,则返回true)和
exists
(它也接受一个谓词,但只需要一个匹配项)非常清楚地编写此代码:

请注意,我没有使用
assert
在无效输入上失败并出现异常这本质上是不起作用的,它破坏了方法类型签名的隐式约定如果我看到返回布尔值的
validate(…)
方法,我将假设如果参数有效,则该值为true,如果不是,则为假。您可以使用一些混合的异常和函数组合来实现与原始版本相同的行为,但我强烈建议不要这样做


我还建议避免在地图上查找可能失败的内容(例如,使用
get
getOrElse
并明确处理错误的可能性),并且不要使用
map[String,Any]

抱歉,我不确定您在这里的具体目的,但我认为它不起作用,使用
“”
作为一种哨兵价值观,而不是非常明确地说,你这样做是一个坏主意。好的观点。移除了哨兵。。。为什么你说它不起作用呢?我很确定它是真的。首先,它总是返回true。是的,除非assert失败。就像OP的要求一样。。。您的版本在这方面实际上是错误的;)OP的代码是相同的。问题在于以函数式的方式重写,而不是优化。Op的代码也总是返回true。。。你的没有;)之所以出现“true”,是因为代码要在Specs2中运行。在Specs2中,您必须返回一个结果(例如,如果测试成功,则返回布尔真)。@suud然后可能使用
must-beTrue
matcher
val ms = mm2.map(m => m.a -> m.b).toMap
mm1.foreach { m => 
    assert(m.get(a).flatMap(ms.get).exists(_ == m("b")))
}

true
def validate(mm1: List[Map[String, Any]], mm2: List[M]) = mm1.forall { m1 =>
  mm2.exists {
    case M(a, b) => a == m1("a") && b == m1("b")
  }
}