sql - 在理解中实现 DISTINCT

标签 sql scala for-comprehension

his Coursera course倒数第二讲, 奥德斯基教授提供了以下 for理解作为一个可爱案例研究的最后一步:

def solutions(target: Int): Stream[Path] =
  for {
    pathSet <- pathSets
    path <- pathSet
    if path.endState contains target
  } yield path

在较早的讲座中,他在 for 之间做了一些类比。理解和 SQL。

我正在寻找的方法是yield只有那些 path具有 DISTINCT 的 s endState .

有没有办法从具有相同理解的过滤器子句中引用已经产生的项目?

另一种方法可能是转换 pathSetsMap来自 endStatepathfor 之前语句,然后将其转换回 Stream在返回之前。然而,这似乎失去了使用 Stream 的惰性计算优势。 .

来自同一案例研究的早期方法实现了类似的目标,但它已经是一个递归函数,而这个(似乎)不需要递归。

看起来我可以使用可变的 Set跟踪 endState s 得到了让步,但感觉并不令人满意,因为到目前为止,该类(class)已成功避免使用可变性。

最佳答案

Is there a way to refer back from within a filter clause of the same comprehension to the items that have already been yielded?



你的理解对某些东西或多或少像
pathSets flatMap {
  pathSet => pathSet filter {
   path => path.endState contains target
  }
} map {path => path}

最后一张带有恒等函数的 map 是你的产量。我不记得当它是一个身份函数时,规范是否允许省略该映射。

无论如何,我希望这能更清楚地说明为什么这种结构没有“回溯”。

您可以编写一个惰性的递归 distinctBy 函数
implicit class DistinctStream[T](s: Stream[T]) {
  def distinctBy[V](f: T => V): Stream[T] = {
    def distinctBy(remainder: Stream[T], seen:Set[V]): Stream[T] =
      remainder match {
        case head #:: tail => 
          val value = f(head)
          if (seen contains value) distinctBy(tail, seen)
          else Stream.cons(head, distinctBy(tail, seen + value))
        case empty => empty
     }

    distinctBy(s, Set())  
  }
}

像这样使用它
def solutions(target: Int): Stream[Path] =
(for {
 pathSet <- pathSets
 path <- pathSet
 if path.endState contains target
} yield path) distinctBy (_.endState)

是的,现在有递归。但是已经有,因为 Stream 的 map、flatMap 和 filter 函数已经都是惰性递归函数。

关于sql - 在理解中实现 DISTINCT,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/24454203/

相关文章:

scala - 如何在 ZIO 中实现不使用潜在大量堆空间的循环

scala - ClassCastException 当 asInstanceOf 用于理解时

带有元组分解的 Scala for-comprehension

scala - 嵌套惰性理解

php - 我如何解决此错误 :SQLSTATE[23000]: Integrity constraint violation: 1062 Duplicate entry '30' for key 'PRIMARY'

Scala - 计算 List[SomeObj] 中 SomeObj.double 的平均值

java - 编译 Spark 类时出现 "Eclipse Plugin for Scala"错误

MySql 当主查询有 groupby 子句时从子查询中选择数据

sql - 运算符不存在 : timestamp without time zone ~~* unknown ruby code

mysql - 查询实体的余额到期日和到期日