我正在尝试编写countWords(ws)函数,该函数计算单词列表中单词的频率,这些单词将从单词返回到出现的地图。 那个ws是一个List [String],使用List数据类型我应该使用Map数据类型生成Map [String,Int]。该函数应该做什么的一个例子:
def test{
expect (Map("aa" -> 2, "bb" -> 1)) {
countWords(List("aa", "bb"))
}
}
这只是一个测试的实施,而不是一个任务。我一直坚持这个功能。这就是我到目前为止所做的:
object Solution {
// define function countWords
def countWords(ws : List[String]) : Map[String,Int] = ws match {
case List() => List()
}
}//
,它给出了类型不匹配。我不太确定如何使用scala Map Function,例如当ws为Empty时,它应该返回Map[String,Int]
我应该返回的内容,这就是为什么我在这里发布它以获得一些帮助。谢谢。
答案 0 :(得分:3)
另一种方法是使用输出groupBy
的{{1}}。然后,您可以使用Map(baz -> List(baz, baz, baz), foo -> List(foo, foo), bar -> List(bar))
映射Map
的值,以计算每个单词出现的次数。
mapValues
关于程序中的类型不匹配scala> List("foo", "foo", "bar", "baz", "baz", "baz")
res0: List[String] = List(foo, foo, bar, baz, baz, baz)
scala> res0.groupBy(x => x).mapValues(_.size)
res0: scala.collection.immutable.Map[String,Int] = Map(baz -> 3, foo -> 2, bar -> 1)
期望countWords
作为返回类型和第一个(也是唯一的)匹配,您返回一个类型为{{1的空Map[String, Int]
}}。如果您将匹配更改为List
,则不会再出现类型错误。它还会给出一个关于详尽模式匹配的警告,显然不会返回正确的输出。
答案 1 :(得分:2)
使用折叠从空地图开始查看列表
ws.foldLeft(Map.empty[String, Int]){
(count, word) => count + (word -> (count.getOrElse(word, 0) + 1))
}
答案 2 :(得分:1)
最简单的解决方案是
def countWords(ws: List[String]): Map[String, Int] = {
ws.toSet.map((word: String) => (word, ws.count(_ == word))).toMap
}
但它不是最快的,因为它多次搜索列表。
编辑:
最快的方法是使用可变的HashMap
def countWords(ws: List[String]): Map[String, Int] = {
val map = scala.collection.mutable.HashMap.empty[String, Int]
for(word <- ws) {
val n = map.getOrElse(word, 0)
map += (word -> (n + 1))
}
map.toMap
}