【问题标题】:Scala's for-comprehension `if` statementsScala 的 for-comprehension `if` 语句
【发布时间】:2011-10-31 13:01:32
【问题描述】:

在 scala 中是否可以在 for 理解中专门研究 if 内的条件?我的想法是:

val collection: SomeGenericCollection[Int] = ...

trait CollectionFilter
case object Even extends CollectionFilter
case object Odd extends CollectionFilter

val evenColl = for { i <- collection if(Even) } yield i
//evenColl would be a SomeGenericEvenCollection instance

val oddColl = for { i <- collection if(Odd) } yield i
//oddColl would be a SomeGenericOddCollection instance

要点是,通过产生i,我得到了一个可能不同类型的新集合(因此我将其称为“专业化”)——而不仅仅是相同 GenericCollection 类型的过滤版本。

我问的原因是我看到了一些我无法弄清楚的东西(可以找到一个示例on line 33 of this ScalaQuery example。它的作用是为数据库创建一个查询(即SELECT ... FROM ... WHERE ...),我会在那里预计它会迭代所述查询的结果。

【问题讨论】:

  • 这个问题没有多大意义。我将回答我认为被问到的问题,但请尝试改进它。
  • 'For expressions' 应该会有所帮助。
  • 我添加了一些内容以试图澄清这个问题,尽管您对我所问的问题的看法似乎是正确的。

标签: scala


【解决方案1】:

所以,我想您是在问,for-comprehension 中的 if 语句是否可以更改结果类型。答案是“是的,但是……”。

首先,了解如何扩展 for-comprehensions。 Stack Overflow 上有一些问题正在讨论它,并且您可以将一些参数传递给编译器,这样它就会告诉您发生了什么。

不管怎样,这段代码:

val evenColl = for { i <- collection if(Even) } yield i

翻译为:

val evenColl = collection.withFilter(i => Even).map(i => i)

所以,如果withFilter 方法改变了集合类型,它会做你想做的——在这个简单的例子中。在更复杂的情况下,仅此一项是行不通的:

for {
  x <- xs
  y <- ys
  if cond
} yield (x, y)

翻译为

xs.flatMap(ys.withFilter(y => cond).map(y => (x, y)))

在这种情况下,flatMap 决定返回什么类型。如果它从返回的结果中得到提示,那么它就可以工作。

现在,在 Scala 集合上,withFilter 不会更改集合的类型。但是,您可以编写自己的类来执行此操作。

【讨论】:

  • 谢谢——我认为withFilter 是我遗漏的关键信息。
【解决方案2】:

是的,您可以 - 请参阅 this tutorial 以获取简单示例。您引用的 scala 查询示例也在对集合进行迭代,然后使用该数据构建查询。

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 2014-07-04
    • 2021-10-08
    • 1970-01-01
    • 2015-12-30
    • 1970-01-01
    • 2023-04-02
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多