Scala:从元组数组/ RDD中获取第n个元素的总和
发布时间:2020-12-16 18:44:23 所属栏目:安全 来源:网络整理
导读:我有一个像这样的元组数组: val a = Array((1,2,3),(2,3,4)) 我想为下面的方法编写泛型方法: def sum2nd(aa: Array[(Int,Int,Int)]) = { aa.map { a = a._2 }.sum } 所以我正在寻找一种方法,如: def sumNth(aa: Array[(Int,Int)],n: Int) 解决方法 有几种
我有一个像这样的元组数组:
val a = Array((1,2,3),(2,3,4)) 我想为下面的方法编写泛型方法: def sum2nd(aa: Array[(Int,Int,Int)]) = { aa.map { a => a._2 }.sum } 所以我正在寻找一种方法,如: def sumNth(aa: Array[(Int,Int)],n: Int) 解决方法
有几种方法可以解决这个问题.最简单的是使用productElement:
def unsafeSumNth[P <: Product](xs: Seq[P],n: Int): Int = xs.map(_.productElement(n).asInstanceOf[Int]).sum 然后(注意索引从零开始,所以n = 1给我们第二个元素): scala> val a = Array((1,4)) a: Array[(Int,Int)] = Array((1,4)) scala> unsafeSumNth(a,1) res0: Int = 5 但是,这种实现可能会在运行时以两种不同的方式崩溃: scala> unsafeSumNth(List((1,2),3)),3) java.lang.IndexOutOfBoundsException: 3 at ... scala> unsafeSumNth(List((1,"a"),"b")),1) java.lang.ClassCastException: java.lang.String cannot be cast to java.lang.Integer at ... 即,如果元组没有足够的元素,或者你要求的元素不是Int. 您可以编写一个在运行时不会崩溃的版本: import scala.util.Try def saferSumNth[P <: Product](xs: Seq[P],n: Int): Try[Int] = Try( xs.map(_.productElement(n).asInstanceOf[Int]).sum ) 然后: scala> saferSumNth(a,1) res4: scala.util.Try[Int] = Success(5) scala> saferSumNth(List((1,3) res5: scala.util.Try[Int] = Failure(java.lang.IndexOutOfBoundsException: 3) scala> saferSumNth(List((1,1) res6: scala.util.Try[Int] = Failure(java.lang.ClassCastException: ... 这是一种改进,因为它迫使呼叫者解决失败的可能性,但它也有点烦人,因为它迫使呼叫者解决失败的可能性. 如果你愿意使用Shapeless,你可以拥有两全其美: import shapeless._,shapeless.ops.tuple.At def sumNth[P <: Product](xs: Seq[P],n: Nat)(implicit atN: At.Aux[P,n.N,Int] ): Int = xs.map(p => atN(p)).sum 然后: scala> sumNth(a,1) res7: Int = 5 但坏的甚至没有编译: scala> sumNth(List((1,3) <console>:17: error: could not find implicit value for parameter atN: ... 但这仍然不完美,因为它意味着第二个参数必须是一个字面数字(因为它需要在编译时知道): 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) ^ 但在许多情况下,这不是问题. 总结一下:如果您愿意为合理的代码崩溃程序负责,请使用productElement.如果您想要更安全一些(以一些不便为代价),请使用带有Try的productElement.如果您想要编译时安全(但有一些限制),请使用Shapeless. (编辑:李大同) 【声明】本站内容均来自网络,其相关言论仅代表作者个人观点,不代表本站立场。若无意侵犯到您的权利,请及时与联系站长删除相关内容! |