Sql 以不同的方式理解
在的倒数第二次讲座中,奥德斯基教授提出了以下关于理解的Sql 以不同的方式理解,sql,scala,for-comprehension,Sql,Scala,For Comprehension,在的倒数第二次讲座中,奥德斯基教授提出了以下关于理解的,作为可爱案例研究的最后一步: def solutions(target: Int): Stream[Path] = for { pathSet <- pathSets path <- pathSet if path.endState contains target } yield path def解决方案(目标:Int):流[路径]= 为了{ 路径集 是否有一种方法可以从具有相同理解的过滤子句中
,作为可爱案例研究的最后一步:
def solutions(target: Int): Stream[Path] =
for {
pathSet <- pathSets
path <- pathSet
if path.endState contains target
} yield path
def解决方案(目标:Int):流[路径]=
为了{
路径集
是否有一种方法可以从具有相同理解的过滤子句中引用已经生成的项目
你的理解或多或少类似于
pathSets flatMap {
pathSet => pathSet filter {
path => path.endState contains target
}
} map {path => path}
最后一个带有标识函数的映射是你的屈服。我不记得规范是否允许在标识函数中省略该映射
无论如何,我希望这能更清楚地说明为什么这种结构没有“回馈”
您可以编写一个惰性的递归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)
def解决方案(目标:Int):流[路径]=
(用于{
pathSet您可以使用递归流定义,但您不能使用用于理解的。当然……使用mutable.Set
确实是简单而有效的。为什么它会给您带来这么多麻烦?map
和flatMap
也可以使用可变性来实现,即使您将它们与for
一起使用re是函数中的易变性,但局外人无权使用这种易变性,这才是重要的。它还可以使代码更具可读性。易变性不是魔鬼:)你能使用Streamála的独特方法吗?如果你已经完成了课程的最后一个作业,如果我没记错的话,有一个函数正好实现了这个动作,它是使用一个累加器完成的,它包含了到目前为止看到的结束状态和一个基于此进行过滤的辅助函数。这非常有用可以。不需要为distinct添加本机支持,Scala的主要思想之一是,您应该能够用语言本身编写所需的扩展,它们看起来就像语言的原语。如果您希望完全不可变,则需要某种由流monad组成的状态monad转换器