There are several ways to do this. The simplest is to use productElement :
def unsafeSumNth[P <: Product](xs: Seq[P], n: Int): Int = xs.map(_.productElement(n).asInstanceOf[Int]).sum
And then (note that indexing starts from zero, so n = 1 gives us the second element):
scala> val a = Array((1, 2, 3), (2, 3, 4)) a: Array[(Int, Int, Int)] = Array((1,2,3), (2,3,4)) scala> unsafeSumNth(a, 1) res0: Int = 5
This implementation may fail at runtime in two different ways:
scala> unsafeSumNth(List((1, 2), (2, 3)), 3) java.lang.IndexOutOfBoundsException: 3 at ... scala> unsafeSumNth(List((1, "a"), (2, "b")), 1) java.lang.ClassCastException: java.lang.String cannot be cast to java.lang.Integer at ...
Ie if the tuple does not have enough elements, or if the requested element is not Int .
You can write a version that does not crash at runtime:
import scala.util.Try def saferSumNth[P <: Product](xs: Seq[P], n: Int): Try[Int] = Try( xs.map(_.productElement(n).asInstanceOf[Int]).sum )
And then:
scala> saferSumNth(a, 1) res4: scala.util.Try[Int] = Success(5) scala> saferSumNth(List((1, 2), (2, 3)), 3) res5: scala.util.Try[Int] = Failure(java.lang.IndexOutOfBoundsException: 3) scala> saferSumNth(List((1, "a"), (2, "b")), 1) res6: scala.util.Try[Int] = Failure(java.lang.ClassCastException: ...
This is an improvement because it forces callers to solve the failure problem, but it is also annoying because it forces callers to eliminate the possibility of failure.
If you want to use Shapeless , you can get the best of both worlds:
import shapeless._, shapeless.ops.tuple.At def sumNth[P <: Product](xs: Seq[P], n: Nat)(implicit atN: At.Aux[P, nN, Int] ): Int = xs.map(p => atN(p)).sum
And then:
scala> sumNth(a, 1) res7: Int = 5
But the bad ones don't even compile:
scala> sumNth(List((1, 2), (2, 3)), 3) <console>:17: error: could not find implicit value for parameter atN: ...
This is still not ideal, as it means that the second argument must be a literal number (since it needs to be known at compile time):
scala> val x = 1 x: Int = 1 scala> sumNth(a, x) <console>:19: error: Expression x does not evaluate to a non-negative Int literal sumNth(a, x) ^
In many cases this is not a problem.
To summarize: if you are willing to take responsibility for reasonable code that crashes your program, use productElement . If you want a little more security (due to some inconvenience), use productElement with Try . If you need compile-time security (but some limitations), use Shapeless.