说明:我接受gzm0's回答,因为它摇摇欲坠!
@Eduardo确实提出了一条意见建议:(for(i <- 10..20; j=runTest(i)) yield i -> j).toMap
这也让我运行构建,他只是从来没有发布过答案,@ gzm0答案在概念上很棒,所以我接受了它。
Once I get this other issue figured out relating to "can't call constructor"我将能够通过实际运行程序LOL
来测试这些问题:我在这个表达式中有一个错误,特别是如何修复它,但更一般地说我错过了关于FP或Scala的错误是什么?
timingsMap = for (i <- powersList; j <- runTest(i)) yield i -> j
我正在编写我的第一个Gradle / Scala项目,用于分析算法分配。 Scala不是作业的一部分,所以我没有使用作业标签。除了我在Java中使用Spark之外,我是功能编程的新手我确信这就是问题所在。
这是一个片段,the full .scala file is on GitHub,如果我被玷污了,或者我会在这里发布完整的程序:)
val powersList = List(10 to 20)
// create a map to keep track of power of two and resulting timings
var timingsMap: Map[Integer, Double] = Map()
// call the runTest function once for each power of two we want, from powersList,
// assign timingsMap the power of 2 value and results of runTest for that tree size
timingsMap = for (i <- powersList; j <- runTest(i)) yield i -> j
错误是: /home/jim/workspace/Scala/RedBlackTree4150/src/main/scala/Main.scala:36:值图不是Double的成员 timingsMap = for(i&lt;-powersList; j&lt; - runTest(i))yield i - &gt; Ĵ
我认为我正在timingsMap = ...
行中执行的操作是将powersList
的所有元素都映射到i
的循环的每次迭代,并且runTest(i)
的每个迭代映射到j
的返回值,然后将所有这些对并放入timingsMap
。这是我尝试在导致问题的i
循环中使用call runTest(i)
的方式吗?
runTest看起来像这样:
def runTest(powerOfTwo: Range): Double = {
// create the tree here
var tree = new TreeMap[Int, Double]
// we only care to create a tree with integer keys, not what the value is
for (x <- powerOfTwo) {
// set next entry in map to key, random number
tree += (x -> math.random)
}
stopWatchInst.start()
// now go through and look up all the values in the tree,
for (x <- powerOfTwo) {
// get the value, don't take the time/overhead to store it in a var, as we don't need it
tree.get(x)
}
// stop watch check time report and return time
stopWatchInst.stop()
val totalTime = stopWatchInst.elapsed(TimeUnit.MILLISECONDS)
loggerInst.info("run for 2 to the power of " + powerOfTwo + " took " + totalTime + " ms")
return totalTime
}
注意:我已经建议在此行中将j <-
更改为=
中的j <-
:timingsMap = for(i&lt; - powersList; j&lt; - runTest (i))产量i - > Ĵ
另一个建议并不喜欢使用yield并建议替换为(10到20).map ...
奇怪的部分是现有的代码在IntelliJ编辑器中没有显示错误,只有在我运行它时才会中断。这些建议都会在IDE中出现类型不匹配错误。我真的想从概念上弄清楚我做错了什么,谢谢你的帮助! (当然,我需要让它发挥作用!)
在尝试gzm0回答之后,我走上了同样的道路......在我使用gradle run
之前,我所呈现的代码没有显示任何类型不匹配...而当我进行建议的更改时,它开始给出我在IDE中的错误...但是让他们来吧!这是基于gzm0s答案的最新错误:
/home/jim/workspace/Scala/RedBlackTree4150/src/main/scala/Main.scala:37: type mismatch;
found : List[(scala.collection.immutable.Range.Inclusive, Double)]
required: Map[Integer,Double]
timingsMap = for (i <- powersList) yield i -> runTest(i)
答案 0 :(得分:3)
你想:
for (i <- powersList)
yield i -> runTest(i)
runTest
的结果不是列表,因此您无法将其提供给for
语句。您收到一些奇怪的错误消息的原因是由于您的for
被解雇了:
for (i <- powersList; j <- runTest(i)) yield i -> j
// turns into
powersList.flatMap { i => runTest(i).map { j => i -> j } }
但是,runTest(i)
的结果是Double
,它没有map
方法。所以看看这个荒谬的,错误信息实际上是有道理的。
请注意,我关于runTest
的结果不是列表的观点并不正确:任何具有map
方法的内容都允许使用上述语句(即采用某种方式lambda)会做的。但是,这超出了这个答案的范围。
我们现在已经成功创建了一个元组列表(因为powersList
是List
,for
循环的结果也是List
。但是,我们需要Map
。幸运的是,您可以在包含元组的toMap
上调用List
将其转换为Map
:
val tups = for (i <- powersList) yield i -> runTest(i)
timingsMap = tups.toMap
请注意:如果您确实要将j
保留在for
循环中,则可以使用等号而不是左箭头:
for (i <- powersList; j = runTest(i)) yield i -> j
这将转变为:
powersList.map { i =>
val j = runTest(i)
i -> j
}
这就是你想要的。