scala - Scala 中的 for 表达式与 foreach

标签 scala loops foreach

我正在努力解决Programming in Scala ,虽然我很想从 Python 的角度看待事物,但我不想编写“Python in Scala”。

就控制流而言,我不太确定该怎么做:在 Python 中,我们使用 for x in some_iterable 到死,而且我们喜欢它。 Scala 中存在一个非常相似的构造,Odersky 将其称为 for 表达式,可能是为了将其与 Java for 循环区分开来。另外,Scala 对于可迭代数据类型有一个 foreach 属性(我猜它是一个属性,我对 Scala 的了解不够,无法正确命名它)。不过,似乎我不能使用 foreach 做更多事情,而不仅仅是为容器中的每一项调用一个函数。

这给我留下了几个问题。首先,Scala 中的 for 表达式是重要/频繁使用的结构,就像在 Python 中一样;其次,我什么时候应该使用 foreach 而不是 for 表达式(除了在每个函数上调用函数的明显情况之外)容器中的元素)?

我希望我没有说得太含糊或过于宽泛,但我只是想了解 Scala 中的一些设计/语言基础知识(到目前为止看起来非常酷)。

最佳答案

python 使用for在列表推导式和生成器表达式中。这些与 scala for 非常相似。表达式:

这是Python

>>> letters = ['a', 'b', 'c', 'd']
>>> ints = [0, 1, 2, 3]
>>> [l + str(i) for l in letters for i in ints if i % 2 == 0]
['a0', 'a2', 'b0', 'b2', 'c0', 'c2', 'd0', 'd2']

这是 scala

scala> val letters = List('a', 'b', 'c', 'd')
scala> val ints = List(0, 1, 2, 3)
scala> for (l <- letters; i <- ints if i % 2 == 0) yield l.toString + i
res0: List[java.lang.String] = List(a0, a2, b0, b2, c0, c2, d0, d2)

每个构造都可以采用多个生成器/迭代器,应用过滤器表达式并生成组合表达式。在Python中(expr for v1 in gen1 if expr1 for v2 in gen2 if expr2)大致相当于:

for v1 in gen1:
  if expr1:
    for v2 in gen2:
      if expr2:
        yield expr

在 scala 中 for (v1 <- gen1 if expr1; v2 <- gen2 if expr2) yield expr大致相当于:

gen1.withFilter(expr1).flatMap(v1 => gen2.withFilter(expr2).map(v2 => expr))

如果你喜欢Python for x in xs语法,您可能会喜欢 scala for表达。

Scala 有一些额外的语法和翻译变化。语法方面 for可以与大括号一起使用,以便可以将语句放在单独的行上。您还可以执行值分配。

val res = for {
    i <- 1 to 20; i2 = i*i
    j <- 1 to 20; j2 = j*j
    k <- 1 to 20; k2 = k*k
    if i2 + j2 == k2
  } yield (i, j, k)

还有v1 <- gen1确实进行了一场比赛case v1 => gen1 。如果没有匹配,则迭代中将忽略这些元素。

scala> val list = List(Some(1), None, Some(2))
scala> for (Some(i) <- list) yield i
res2: List[Int] = List(1, 2)

我认为for在语言中占有重要地位。我可以从你正在阅读的书中有一整章(23)来介绍它!

关于scala - Scala 中的 for 表达式与 foreach,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/4466362/

相关文章:

javascript - 在 for 循环中使用现有变量

mysql - foreach 循环中 codeigniter 中出现 500 内部服务器错误和 undefined variable 错误?

r - foreach 和 dopar 返回 NULL 而不是所需的答案

java - 没有 Apache Spark 的复杂内存对象到 Parquet 文件

algorithm - 在 Scala 中,按组合键对列表进行排序的正确方法是什么

java - 接受输入时无休止的java循环

javascript - 当一个简单的 For Loop 工作正常时,我的 forEach 方法有什么问题

Scala.Either orElse 方法

scala - WSClient Play Framework SSL 设置

python - 在 python open csv 中构建字典内的列表