为了理解而对此感到困惑

时间:2014-07-24 10:25:23

标签: scala

下面的代码是将每个内部数组的元素相乘,并将这些元素作为数组返回:

object tupletest {
  println("Welcome to the Scala worksheet")       //> Welcome to the Scala worksheet

  val data = Array(("a", Array((1.0, 2.0))), ("b", Array((3.0, 4.0))))
                                                  //> data  : Array[(String, Array[(Double, Double)])] = Array((a,Array((1.0,2.0))
                                                  //| ), (b,Array((3.0,4.0))))

  for {

    (s, tuples) <- data

    sum1 = tuples.map(_._1).sum
    sum2 = tuples.map(_._2).sum

  } yield sum1 * sum2                             //> res0: Array[Double] = Array(2.0, 12.0)

http://www.scala-lang.org/old/node/111阅读有关理解的解释我仍然不明白如何评估上述代码?

这对于理解是否类似于嵌套for循环?

如果我尝试访问Array的第二个元素,则抛出java.lang.ArrayIndexOutOfBoundsException:

for {

    (s, tuples) <- data

    sum1 = tuples(1)

  } yield tuples                                  //> java.lang.ArrayIndexOutOfBoundsException: 1

但是这不应该发生,因为每个数组的大小都是2?

更新:

为什么要使用:

for {

    (s, tuples) <- data

    sum1 = tuples.map(_._1).sum
    sum2 = tuples.map(_._2).sum

  } yield sum1 * sum2                             //> res0: Array[Double] = Array(2.0, 12.0)

而不是:

  data.map { case (s, tuples) =>

    val sum1 = tuples.map(_._1).sum
    val sum2 = tuples.map(_._2).sum

    sum1 * sum2
    }  

使用地图功能不清楚吗?

这个问题/答案也有助于解释这个问题:

Confused with the for-comprehension to flatMap/Map transformation

1 个答案:

答案 0 :(得分:1)

tuples是指Array((1.0, 2.0))Array((3.0, 4.0)),它们都只包含一个元素。因此,tuples(1)是一个超出界限的错误。

代码等同于以下内容:

data.map { case (s, tuples) =>
    val sum1 = tuples(1)
    tuples
}

您是否使用for理解或map是个人选择。如果您有for后跟flatMap链,或者您希望模式匹配失败并想忽略它,那么map最有用。