如何以惯用的方式在scala中制作嵌套的toSet



是否有更惯用的方法将嵌套序列更改为嵌套集?

def toNestedSet[T](tsss: Seq[Seq[Seq[T]]]): Set[Set[Set[T]]]  = 
tsss.map(_.map(_.toSet).toSet).toSet

有可能实现一个可以处理任何深度列表的函数吗?

这实际上一点也不坏(关于这种方法的一些额外讨论,请参阅我对类似问题的回答):

trait Setsifier[I, O] { def apply(i: I): O }
object Setsifier {
def apply[I, O](f: I => O) = new Setsifier[I, O] { def apply(i: I) = f(i) }
implicit def base[I](implicit ev: I <:!< Seq[_]) = apply((_: Seq[I]).toSet)
implicit def rec[I, O](implicit s: Setsifier[I, O]) =
apply((_: Seq[I]).map(s(_)).toSet)
}
def setsify[I, O](i: I)(implicit s: Setsifier[I, O]) = s(i)

然后:

scala> println(setsify(Seq(Seq(Seq(Seq(1)), Seq(Seq(2, 3))))))
Set(Set(Set(Set(1)), Set(Set(2, 3))))

静态键入为Set[Set[Set[Set[[Int]]]]和all。

嗯,我撒了一点谎。上面的<:!<实际上不在标准库中。不过,它是无定形的,或者你可以非常非常容易地自己定义它:

trait <:!<[A, B]
implicit def nsub[A, B] : A <:!< B = new <:!<[A, B] {}
implicit def nsubAmbig1[A, B >: A] : A <:!< B = sys.error("Don't call this!")
implicit def nsubAmbig2[A, B >: A] : A <:!< B = sys.error("Don't call this!")

仅此而已。

要解决问题的第二部分(处理任意深度的列表),可以这样做(类型擦除会有点妨碍):

def toNestedSet(ts: Seq[Any]): Set[Any] = {
ts.foldLeft[Set[Any]](Set())((acc, b) => b match {
case s: Seq[_] => acc + toNestedSet(s)
case x => acc + x
})
} 

注意:快速且脏——它可以工作,但很容易损坏:)

编辑:演员阵容是多余的

相关内容

  • 没有找到相关文章

最新更新