Scala错误“值映射不是Double的成员”

时间:2016-01-25 02:08:22

标签: scala dictionary functional-programming

说明:我接受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)

1 个答案:

答案 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)会做的。但是,这超出了这个答案的范围。

我们现在已经成功创建了一个元组列表(因为powersListListfor循环的结果也是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
}

这就是你想要的。

相关问题