我是
Scala的新手,非常感谢任何帮助(到处都是,并且花了最后8个小时试图解决这个问题)
目前我有
def apply(file: String) : Iterator[String] = {
scala.io.Source.fromFile(file).getLines().map(_.toLowerCase)
}
以及
def groupFreq[A,B](xs: Iterator[A], f: A => B): HashMap[B, Int] = {
var freqMap = new HashMap[B, Int]
for (x <- xs) freqMap = freqMap + ( f(x) -> ( freqMap.getOrElse( f(x) , 0 ) +1 ) )
freqMap
}
apply只需要一个我们传入的单词文件.
GroupFreq采用xs:Iterator [A]和一个将A值转换为B组的分组函数f.
该函数返回一个HashMap,对于每个B组,计算落入该组的A值的数量.
我使用这两个函数来帮助我使用charFreq,这个函数同时使用apply和groupFreq传回一个HashMap,它计算Char在整个文件中出现的次数.如果char没有出现在文件中的任何位置,那么它应该没有映射.
def charFreq(file: String): HashMap[Char, Int] =
{
var it = Iterator[Char]()
val words = apply(file)
for {
xs<-words
} yield { it = it ++ xs.toIterator }
val chars = it
val grouper = (x: Char) => x
groupFreq(chars, grouper)
}
我的解决方案编译并应用和groupFreq按预期工作,但是当我运行charFreq时,它说
charFreq threw an exception: java.util.NoSuchElementException: key not
found: d
我相信我做错了什么,最有可能是我的for循环和屈服,但我已经多次经历了这个逻辑,我不明白为什么它不起作用.
谷歌和StackOverflow推荐使用平面地图,但我也无法做到这一点.
任何帮助,将不胜感激.请记住,这是一个设置了骨架方法的类赋值,因此我无法更改apply和groupFreq和charFreq的设置方式,我只能操作我试图做的实体.
最佳答案 我无法使用一些字符串的随机文本文件重现您的错误.我怀疑它发生在groupFreq()的早期迭代中,没有getOrElse()类型测试.
但是,在运行代码时,我最终会调用charFreq()调用一个空映射.你是正确的,charFreq()中的循环/产量是有问题的.当你在for前面放置一个val l =并检查IDE中的值时,会更容易看到l的类型为Iterator [Unit].
你不需要for循环的变量. for循环与C-style for循环不同,相当于在其元素上调用flatMap / map(尽管其他人可以比我更好地表达它).产量被连接到你的东西(由你在其中采取的步骤定义).
以下两种方法可以为您调用groupFreq()获取Iterator [Char]:
1 GT;删除不必要的var并使用for comprehension循环直接填充chars:
val chars = for {
xs<-words
i<-xs.toIterator
} yield { i }
2 – ;直接在val上调用flatMap:
val chars = words.flatMap( s => s )