是否有更惯用的方法将嵌套序列更改为嵌套集?
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
})
}
注意:快速且脏——它可以工作,但很容易损坏:)
编辑:演员阵容是多余的