如何以惯用的方式在scala中创建嵌套的toSet?

goo*_*zez 7 scala nested list set seq

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

def toNestedSet[T](tsss: Seq[Seq[Seq[T]]]): Set[Set[Set[T]]]  = 
   tsss.map(_.map(_.toSet).toSet).toSet
Run Code Online (Sandbox Code Playgroud)

是否可以实现一个可以处理任何深度列表的函数?

Tra*_*own 8

这实际上并不是太糟糕(请参阅我在这里回答类似问题以获得对此方法的一些额外讨论):

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)
Run Code Online (Sandbox Code Playgroud)

然后:

scala> println(setsify(Seq(Seq(Seq(Seq(1)), Seq(Seq(2, 3))))))
Set(Set(Set(Set(1)), Set(Set(2, 3))))
Run Code Online (Sandbox Code Playgroud)

静态输入为a 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!")
Run Code Online (Sandbox Code Playgroud)

这就是全部.


Jam*_*dam 3

为了解决问题的第二部分(处理任意深度的列表),类似这样的事情会起作用(类型擦除有点妨碍):

  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
    })
  } 
Run Code Online (Sandbox Code Playgroud)

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

编辑:演员阵容是多余的