How to make toSet nested in scala in an idiomatic way?

Is there a more idiomatic way to change a nested sequence of sequences in a nested set of sets?

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

Is it possible to implement a function that will work with lists of any depth?

+7
list set scala nested seq
source share
2 answers

To solve the second part of your question (by processing a list of arbitrary depth), something like this will work (erasing the type is a bit broken):

  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 }) } 

Note: quick and dirty - it works, but pretty easy to break :)

Edit: casting was redundant

+3
source share

This is actually not so bad (see my answer here to a similar question for some further discussion of this approach):

 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) 

And then:

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

Statically printed as Set[Set[Set[Set[[Int]]]] and all.

Well, I lied a little. <:!< above is not in the standard library. However, in Shapeless , or you can very easily define it yourself:

 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!") 

And that’s really all.

+8
source share

All Articles