斯卡拉:数字

时间:2015-04-08 16:04:34

标签: scala dictionary functional-programming

我正在尝试编写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]我应该返回的内容,这就是为什么我在这里发布它以获得一些帮助。谢谢。

3 个答案:

答案 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
}