将一系列映射操作转换为 for 理解式

发布于 2024-11-27 05:07:01 字数 713 浏览 0 评论 0原文

我在《Scala 编程》第 23.5 节中读到,map、flatMap 和过滤器操作始终可以转换为 for 推导式,反之亦然。

我们得到以下等价关系:

def map[A, B](xs: List[A], f: A => B): List[B] =
  for (x <- xs) yield f(x)

我有一个通过一系列映射操作计算出的值:

val r = (1 to 100).map{ i => (1 to 100).map{i % _ == 0} }
                  .map{ _.foldLeft(false)(_^_) }
                  .map{ case true => "open"; case _ => "closed" }

我想知道这作为 for-compression 会是什么样子。我该如何翻译它?

(如果有帮助的话,换句话说,这就是:

  • 为每个整数取 1 到 100 之间的整数
  • ,创建一个包含 100 个布尔值的列表,
  • 用 XOR 运算符折叠每个列表,返回到一个布尔值,
  • 生成一个包含 100 个“打开”或“关闭”字符串的列表“根据布尔值,

我想有一个标准方法来翻译地图操作,并且其中实际功能的细节并不重要。不过我可能是错的。)

I read in Programming in Scala section 23.5 that map, flatMap and filter operations can always be converted into for-comprehensions and vice-versa.

We're given the following equivalence:

def map[A, B](xs: List[A], f: A => B): List[B] =
  for (x <- xs) yield f(x)

I have a value calculated from a series of map operations:

val r = (1 to 100).map{ i => (1 to 100).map{i % _ == 0} }
                  .map{ _.foldLeft(false)(_^_) }
                  .map{ case true => "open"; case _ => "closed" }

I'm wondering what this would look like as a for-comprehension. How do I translate it?

(If it's helpful, in words this is:

  • take integers from 1 to 100
  • for each, create a list of 100 boolean values
  • fold each list with an XOR operator, back into a boolean
  • yield a list of 100 Strings "open" or "closed" depending on the boolean

I imagine there is a standard way to translate map operations and the details of the actual functions in them is not important. I could be wrong though.)

如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。

扫码二维码加入Web技术交流群

发布评论

需要 登录 才能够评论, 你可以免费 注册 一个本站的账号。

评论(1

素食主义者 2024-12-04 05:07:01

这是您正在寻找的翻译吗?

for (i <- 1 to 100;
     val x = (1 to 100).map(i % _ == 0);
     val y = x.foldLeft(false)(_^_);
     val z = y match { case true => "open"; case _ => "closed" })
  yield z

如果需要,x 定义中的 map 也可以转换为“内部”理解。

回想起来,一系列链式 map 调用有点微不足道,因为您可以等效地使用组合函数调用 map 一次:

 s.map(f).map(g).map(h) == s.map(f andThen g andThen h)

我发现 for-compressions 是一个更大的胜利当涉及到 flatMapfilter 时。考虑

for (i <- 1 to 3;
     j <- 1 to 3 if (i + j) % 2 == 0;
     k <- 1 to 3) yield i ^ j ^ k

(1 to 3).flatMap { i =>
  (1 to 3).filter(j => (i + j) % 2 == 0).flatMap { j =>
    (1 to 3).map { k => i ^ j ^ k }
  }
}

Is this the kind of translation you're looking for?

for (i <- 1 to 100;
     val x = (1 to 100).map(i % _ == 0);
     val y = x.foldLeft(false)(_^_);
     val z = y match { case true => "open"; case _ => "closed" })
  yield z

If desired, the map in the definition of x could also be translated to an "inner" for-comprehension.

In retrospect, a series of chained map calls is sort of trivial, in that you could equivalently call map once with composed functions:

 s.map(f).map(g).map(h) == s.map(f andThen g andThen h)

I find for-comprehensions to be a bigger win when flatMap and filter are involved. Consider

for (i <- 1 to 3;
     j <- 1 to 3 if (i + j) % 2 == 0;
     k <- 1 to 3) yield i ^ j ^ k

versus

(1 to 3).flatMap { i =>
  (1 to 3).filter(j => (i + j) % 2 == 0).flatMap { j =>
    (1 to 3).map { k => i ^ j ^ k }
  }
}
~没有更多了~
我们使用 Cookies 和其他技术来定制您的体验包括您的登录状态等。通过阅读我们的 隐私政策 了解更多相关信息。 单击 接受 或继续使用网站,即表示您同意使用 Cookies 和您的相关数据。
原文