计算字母出现的次数,并将字典放在列表中

时间:2019-03-25 19:14:27

标签: scala

我试图计算字符串流中字母的出现次数,然后将每个字符串的映射(“字母”->计数)放入列表中。

def checksum(ipt: Stream[String]) =  ipt.foldLeft(List(Map("x"->1)))( (n: 
List[Map[String, Int]], m: String)  => n ++ 
m.split("").groupBy(identity).mapValues(_.size).toMap)

出现问题:

 Expression of type List[Equals] doesn't conform to expected type List[Map[String, Int]]

怎么了?就像对每个字符串这样做都没有问题:

 def checksum(ipt: Stream[String]) =  ipt.foreach( (m: String)  => println(m.split("").groupBy(identity).mapValues(_.size)))

它在

上给出类似的内容
val s = "bababc"
val d = "abbcde"
checksum(List(s,d).toStream)
out: 
Map(b -> 3, a -> 2, c -> 1)
Map(e -> 1, a -> 1, b -> 2, c -> 1, d -> 1)

但是我现在如何将所有这些地图存储在列表中?我不能使用vars,而需要在一个表达式中完成。

1 个答案:

答案 0 :(得分:0)

如果每个字符串都需要一个映射,则可以使用第一个流上的映射函数来实现它,如下所示:

 def checksums(ipt: Stream[String]): Stream[Map[Char, Int]] = {
    ipt.map(checksum)
 }

 def checksum(ipt: String): Map[Char, Int] = ipt.foldLeft(Map.empty[Char, Int]) { case (acc, ch) =>
     acc.get(ch) match {
        case Some(q) => acc + (ch -> (q + 1))
        case None => acc + (ch -> 1)
     }
 }

回到您的代码,将元素添加到列表的操作员是:+,而不是++。

++用于连接列表。

因此您可以像这样修复代码:

def checksumFixed(ipt: Stream[String]) = {
    ipt.foldLeft(List(Map("x"->1))) { (n: List[Map[String, Int]], m: String) =>
      n :+ m.split("").groupBy(identity).mapValues(_.length)
    }
  }