在Map中递归遍历值

时间:2015-03-19 22:35:16

标签: scala scala-collections scala-2.10 scalaz

我试图以递归方式Map[String,List[String]]来提取并展平与地图相关的所有值

val x = Map("a" -> List("b","c","d"), "b" -> List("f","g","h"), "f" -> List("i","j","k"), "g" -> List("p","q","r"))
  1. 对于每个键,提取值,即List
  2. 对于List的值中的每个项目:
    • 检查密钥是否存在,然后提取值
  3. 继续以递归方式执行此操作,直到键没有值并且为键

    列出flatten值

    结果应为

    Map("a" -> List("b","c","d","f","g","h","i","j","k","p","q","r"), 
        "b" ->  List("f","g","h","i","j","k","p","q","r"), 
        "f" -> List("i","j","k"), 
        "g" -> List("p","q","r"))
    

2 个答案:

答案 0 :(得分:3)

你可以尝试迭代,直到没有变化:

def getValues(dict: Map[String, List[String]]) = Iterator.iterate(dict) { _.mapValues { 
        _.flatMap(v => v :: dict.get(v).toList.flatten).toSet.toList
    } filterNot { _._2.isEmpty }
}.sliding(2) find { x => x.head == x.last }

这绝对不是最有效的解决方案,但它非常简洁!

答案 1 :(得分:1)

试试这段代码:

def f(map: Map[String, List[String]]): Map[String, List[String]] = {
  def f(x: Map[String, List[String]], acc: Map[String, List[String]]): Map[String, List[String]] = {
    if (x.isEmpty) acc
    else {
      val keys = x.keySet
      val (complex, simple) = x partition {_._2 exists {s => keys contains s}}

      val newX =
        (for ((ck, cl) <- complex)
        yield (ck -> (simple.filter(x => cl.contains (x._1)).map(_._2).flatten ++ cl).toList)).toMap

      f(newX, acc ++ simple)
    }
  }

  f(map, Map.empty)
}

val x = Map("a" -> List("b","c","d"), "b" -> List("f", "g", "h"), "f" -> List("i","j","k"), "g" -> List("p","q","r"))

println(f(x)) //Map(f -> List(i, j, k), g -> List(p, q, r), b -> List(i, j, k, p, q, r, f, g, h), a -> List(i, j, k, p, q, r, f, g, h, b, c, d))

然而,假设地图中没有递归,例如("a" -> List("b")), ("b" -> List("a")。如果它发生,该函数将以无限循环结束。您必须添加额外的代码来处理这种情况。