The problem you’re running into is that Set has a variable arity, Tuple has fixed arity (that’s difficult to abstract over), and you want to transpose those. That leads to an impedence mismatch that makes things not look so nice.
Your first attempt looks close, but has some syntax and inference issues.
As a first step, close to your original solution, I have
val tupleSets = Set((2,3,5), (3,4,6), (4,5,7))
tupleSets.foldLeft((Set.empty[Int],Set.empty[Int],Set.empty[Int])){
case ((s1, s2, s3), (a,b,c)) => ((s1 + a), (s2 + b), (s3 + c))
}
which gives a (Set[Int], Set[Int], Set[Int])
.
you can trivially get that to a Set, val s = Set(t._1, t._2, t._3)
, but again, it’s a bit less pretty.
Alternatively, you could turn it around, and convert the tuples first. Then you can use stdlib transpose.
Set((2,3,5), (3,4,6), (4,5,7)).map({ case (a, b, c) => List(a, b, c)}).transpose
None of it is exactly clean, but the dirt is going back and forth with lists and tuples, which is IMO forgivable.
Transscript:
C:\Users\marti>scala
Welcome to Scala 2.12.8 (Java HotSpot(TM) 64-Bit Server VM, Java 1.8.0_191).
Type in expressions for evaluation. Or try :help.
scala> val tupleSets = Set((2,3,5), (3,4,6), (4,5,7))
tupleSets: scala.collection.immutable.Set[(Int, Int, Int)] = Set((2,3,5), (3,4,6), (4,5,7))
scala> tupleSets.foldLeft((Set.empty[Int],Set.empty[Int],Set.empty[Int])){
| case ((s1, s2, s3), (a,b,c)) => ((s1 + a), (s2 + b), (s3 + c))
| }
res0: (scala.collection.immutable.Set[Int], scala.collection.immutable.Set[Int], scala.collection.immutable.Set[Int]) = (Set(2, 3, 4),Set(3, 4, 5),Set(5, 6, 7))
scala> Set(res0._1, res0._2, res0._3)
res1: scala.collection.immutable.Set[scala.collection.immutable.Set[Int]] = Set(Set(2, 3, 4), Set(3, 4, 5), Set(5, 6, 7))
scala> tupleSets.map{ case (a, b, c) => List(a, b, c)}.transpose
res2: scala.collection.immutable.Set[scala.collection.immutable.Set[Int]] = Set(Set(2, 3, 4), Set(3, 4, 5), Set(5, 6, 7))