2015-04-08 3 views
-1

Я пытаюсь написать функцию countWords (ws), которая подсчитывает частоту слов в списке слов ws, возвращающих карту от слов к вхождениям. , что ws - это List [String], используя тип данных List, я должен создать Map [String, Int], используя тип данных Map. пример того, что следует делать функция:Scala: Count Words

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 является пустым списком, что он должен вернуть, который прошел Map[String,Int] Я пытался, и именно поэтому я размещаю его здесь, чтобы получить некоторую помощь. Спасибо.

ответ

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 
} 
+0

ничего себе, огромное спасибо, любые советы для меня о том, как делать такого рода вещи? Я довольно новичок в scala. – David

+0

Посмотрите документацию api http://www.scala-lang.org/api/current и прочитайте руководства по коллекциям scala и scala. – SpiderPig

3

Другой способ сделать это состоит в использовании groupBy, который выводит 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 ожидает Map[String, Int] как тип возвращаемого значения и первым (и только) совпадают у вас есть возвращает пустой List с типом Nothing. Если вы измените матч с case List() => Map[String, Int](), то больше ничего не будет отображаться. Он также дает предупреждение об исчерпывающем совпадении шаблонов, очевидно, не вернет правильный результат.

+0

что есть: _.size ??? – David

+0

@david 'size' возвращает количество элементов в коллекции. например 'List (" a "," b "," c "). Size' возвращает' 3'. – Brian

2

Используйте сгиб, чтобы пройти через свой список, начиная с пустой картой

ws.foldLeft(Map.empty[String, Int]){ 
(count, word) => count + (word -> (count.getOrElse(word, 0) + 1)) 
} 
+0

wow, огромное спасибо, любые советы для меня о том, как делать такие вещи? Я довольно новичок в scala. – David

+0

Я сделал курс scala на coursera, очень рекомендую Он смешивает идеальное количество теории с практическим кодированием, взорвал мой разум –