【问题标题】:value foreach is not a member of Int?value foreach 不是 Int 的成员吗?
【发布时间】:2015-09-24 14:29:40
【问题描述】:

我正在学习 scala,我需要打印 2 的幂及其从 0 到 20 的倒数

我正在做的是

scala> for {
     | i <- 0 to 20
     | pow <- scala.math.pow(2, i).toInt
     | rec <- 1/pow
     | } println(pow + "\t" + rec)

但我认为错误为

<console>:13: error: value foreach is not a member of Int
       pow <- scala.math.pow(2, i).toInt
                                   ^

我知道pow 是不可迭代的,但是我之前如何计算它以便我重复使用它?

否则,我将其重新计算为

scala> for(i <- 0 to 10) println(scala.math.pow(2, i).toInt + "\t" + 1/scala.math.pow(2,i))
1   1.0
2   0.5
4   0.25
8   0.125
16  0.0625
32  0.03125
64  0.015625
128 0.0078125
256 0.00390625
512 0.001953125
1024    9.765625E-4

丑,对吧?

【问题讨论】:

    标签: scala


    【解决方案1】:

    当您在 for 理解中使用 &lt;- 时,您需要提供与第一个此类 &lt;- 的输出兼容的类型。在这里,您从i &lt;- 0 to 20 行创建Seq[Int],然后从下一行创建Int。相反,您可以只分配中间结果,并在最后生成一个列表(然后您可以打印出来或根据您的选择使用其他方式)。

    此外,您应该注意,通过转换为 Int,您可以确保使用整数除法计算倒数,这会导致除第一个幂之外的所有倒数为零 - 转换为 @987654327 @ 在收益中,所以你有 Double 倒数。

    总体:

    val result = for {
         i <- 0 to 20
         pow = scala.math.pow(2, i)
         rec = 1/pow
    } yield (pow.toInt + "\t" + rec)
    

    然后您可以使用以下方式打印出结果:

    println(result.mkString("\n"))
    

    然后输出将类似于:

    1   1.0
    2   0.5
    4   0.25
    8   0.125
    16  0.0625
    32  0.03125
    64  0.015625
    128 0.0078125
    256 0.00390625
    512 0.001953125
    1024    9.765625E-4
    2048    4.8828125E-4
    4096    2.44140625E-4
    8192    1.220703125E-4
    16384   6.103515625E-5
    32768   3.0517578125E-5
    65536   1.52587890625E-5
    131072  7.62939453125E-6
    262144  3.814697265625E-6
    524288  1.9073486328125E-6
    1048576 9.5367431640625E-7
    

    此外,您可以更改产量以生成元组列表,然后按您以后选择的方式进行格式化(从生成中解耦格式化):

    val result = { ... // as before
    } yield (i, pow, rec) // Could prove handy to keep the index, and keep pow as a Double for now
    
    def printResults(results: List[(Int, Double, Double)], formatter: (Int, Double, Double) => String) = results forEach { case (n, pow, rec) =>
      println(formatter(n, pow, rec))
    }
    
    def egFormatter(n: Int, pow: Double, rec: Double) = s"For n = $n,\t 2^n = ${pow.toInt},\t reciprocal = $rec"
    
    printResults(results, egFormatter)
    

    【讨论】:

      【解决方案2】:

      一种完全不同的方法,使用Streams,提供了一些灵活性(输出的长度由调用者选择,而不是硬编码)和记忆(在计算出一个值之后,它可以被检索而不是重新计算)。

      // pts --> Powers of Two Stream
      val pts: Stream[(Int,Double)] = (1,1.0) #:: fs.zipWithIndex.map{x=>
                                         val p = scala.math.pow(2, x._2+1);
                                         (p.toInt, 1/p)}
      
      scala> pts.take(20).mkString("\n")
      res11: String =
      (1,1.0)
      (2,0.5)
      (4,0.25)
      (8,0.125)
      (16,0.0625)
      (32,0.03125)
      (64,0.015625)
      (128,0.0078125)
      (256,0.00390625)
      (512,0.001953125)
      (1024,9.765625E-4)
      (2048,4.8828125E-4)
      (4096,2.44140625E-4)
      (8192,1.220703125E-4)
      (16384,6.103515625E-5)
      (32768,3.0517578125E-5)
      (65536,1.52587890625E-5)
      (131072,7.62939453125E-6)
      (262144,3.814697265625E-6)
      (524288,1.9073486328125E-6)
      

      输出格式留给读者练习。

      【讨论】:

        猜你喜欢
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 2019-08-10
        • 1970-01-01
        • 1970-01-01
        • 2020-03-25
        • 1970-01-01
        • 1970-01-01
        相关资源
        最近更新 更多