如何使用折叠在Scala中创建不变地图?

时间:2018-11-19 09:03:31

标签: scala

我正在尝试使用以下代码创建不可变的哈希Map [String,(String,Int)]:

def genList(xx: String) = {
    Seq("one", "two", "three", "four")
}

val oriwords = Set("hello", "how", "are", "you")

val newMap = (Map[String, (String, Int)]() /: oriwords) (
    (cmap, currentWord) => {
        val xv = 2

        genList(currentWord).map(ps => {
            val src = cmap get ps

            if(src == None) {
                cmap + (ps -> ((currentWord, xv)))
            }
            else {
                if(src.get._2 < xv) {
                    cmap + (ps -> ((currentWord, xv)))
                }
                else cmap
            }

        })
    }
)

使用此代码,我得到以下异常:

error: type mismatch;
 found   : Seq[scala.collection.immutable.Map[String,(String, Int)]]
 required: scala.collection.immutable.Map[String,(String, Int)]
               genList(currentWord).map(ps => {
                                       ^

我知道它返回list的{​​{1}},而不是折叠操作的Map[String, (String, Int)]更新。不幸, 我得到任何指示如何解决它。我是Scala的新手。

预期输出为:

Map[String, (String, Int)]

2 个答案:

答案 0 :(得分:1)

使用折页:

def genList(xx: String) = {
    Seq("one", "two", "three", "four")
}

val oriwords = Set("hello", "how", "are", "you")

val newMap = (Map[String, (String, Int)]() /: oriwords) (
    (cmap, currentWord) => {
        val xv = 2

        genList(currentWord).map(ps => {
            val src = cmap get ps

            if(src == None) {
                cmap + (ps -> ((currentWord, xv)))
            }
            else {
                if(src.get._2 < xv) {
                    cmap + (ps -> ((currentWord, xv)))
                }
                else cmap
            }

        }).fold(Map[String, (String, Int)]())((a, b) => a ++ b)
    }
)
println(newMap) //Map(one -> (hello,2), two -> (hello,2), three -> (hello,2), four -> (hello,2))

答案 1 :(得分:1)

您的foldLeft返回的累加器应为Seq[Map[String, (String, Int)]]的类型为Map[String, (String, Int)]

如上所述,原因是因为您正在map上调用Seq并返回Seq。您可以使用foldLeft

解决问题
  def genList(xx: String) = {
    Seq("one", "two", "three", "four")
  }

  val oriwords = Set("hello", "how", "are", "you")

  val newMap = (Map[String, (String, Int)]() /: oriwords) (
    (cmap, currentWord) => {
      val xv = 2

      genList(currentWord).foldLeft(cmap) {
        (acc, ps) => {
          val src = acc get ps

          if (src == None) {
            acc + (ps -> ((currentWord, xv)))
          }
          else {
            if (src.get._2 < xv) {
              acc + (ps -> ((currentWord, xv)))
            }
            else acc
          }

        }
      }
    }
  )

  println(newMap)

Map(one -> (hello,2), two -> (hello,2), three -> (hello,2), four -> (hello,2))

但是输出与期望值不匹配,因此您将需要检查逻辑...