【问题标题】:Scala error "value map is not a member of Double"Scala 错误“值映射不是 Double 的成员”
【发布时间】:2016-05-01 06:12:45
【问题描述】:

说明:我接受了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 的工作外,我对函数式编程是全新的,我确信这就是问题所在。

这是一个 sn-p,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 j

认为我在timingsMap = ... 行中所做的是将powersList 的所有元素映射到循环的每次迭代的i,以及@987654330 的返回值@ 在每次迭代中映射到 j,然后将所有这些对放入 timingsMap。是我试图在循环中使用icall 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 &lt;- 中的 j &lt;- 更改为 = 在这一行:timingsMap = for (i j

另一个建议根本不喜欢使用 yield 并建议用 (10 to 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)

【问题讨论】:

  • 在课堂上去掉括号 RedBlackTree4150() 没什么区别我可以看到...我可以通过 Safari 书籍访问学习 Scala 和 Wampler 的 Programming Scala 所以如果那里有很好的参考,请使用章节/章节标题不是页码谢谢:)
  • 贴了一个答案,但是变成了长篇讨论,他不想去聊天,但愿那个用户没有删除答案!他们建议我使用 (10 to 20).map 之类的东西,但我们遇到了很多类型不匹配的问题。我认为我对for ... yield 所做的事情与地图一样,在引擎盖下。有没有理由避免for ... yield?该用户不喜欢它。
  • j = runTest(i)= 一起使用,而不是&lt;-&lt;- 符号用于收藏时。 runTest 只返回一个 Double
  • 非常有帮助,让我查看 Scala 规范以了解更多信息,但我仍然遇到类型不匹配 /home/jim/workspace/Scala/RedBlackTree4150/src/main/scala/Main.scala:36: type mismatch; found : List[(scala.collection.immutable.Range.Inclusive, Double)] required: Map[Integer,Double] timingsMap = for (i &lt;- powersList; j = runTest(i)) yield i -&gt; j
  • 好的。我认为,一旦达到这一点,您可以通过将整个 for/yield 表达式括在括号中并调用 .toMap 来修复它

标签: scala dictionary functional-programming


【解决方案1】:

你想要:

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 是一个Listfor 循环的结果也是一个List)。但是,我们想要一个Map。幸运的是,您可以在包含元组的Lists 上调用toMap,将它们转换为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
}

这是你想要的。

【讨论】:

  • 我输入了timingsMap = for (i &lt;- powersList) yield i -&gt; runTest(i) 并得到了这个错误:/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 &lt;- powersList) yield i -&gt; runTest(i) 为了便于阅读,我将把它编辑到我的问题中
  • @ChrisMartin 我知道。添加了更多解释。还是不够清楚,我会改进的。
  • 让我阅读您修改后的答案,我将错误添加到答案的末尾...非常感谢大家的建议,但他们让我走上了类型不匹配的道路...如果可以的话领导某处:) .... AHHHH 刚刚阅读了您的扩展答案非常酷,谢谢让我试试,这就是我一直在等待的解释!
  • 不是还有错误吗?在我的回答中,我将Map[Range, Double] 分配给Map[Integer, Double]。您是否希望地图包含范围 -> 时间或点 -> 时间映射?
  • 叮叮叮!!! (好丁)我们有一个赢家。非常完整的答案,这完全解释了为什么我在 IDE 中没有看到错误,只是在运行时。感谢您的超级解释,它现在运行并且在我问的另一个问题中只有两个错误。你这个大男人!顺便说一句,另一个问题是stackoverflow.com/questions/34983987/…,我认为这真的很简单,所以我很惊讶没有人跳上它,再次感谢!!!!
猜你喜欢
  • 2019-09-10
  • 2015-10-29
  • 1970-01-01
  • 2023-03-09
  • 1970-01-01
  • 2021-02-26
  • 2015-10-03
  • 2013-03-10
  • 1970-01-01
相关资源
最近更新 更多