我试图总结偶数项目,然后我去制作元组并总结其中的第一个值,但它创建了很多立即被丢弃的对象。
也许有人可以建议更轻量级的解决方案(也许是fold
)?
编辑:我的意思是偶数位置的数字
测试用例:
List(1,3,1,3).foldLeft(x)(magic) === 2
答案 0 :(得分:4)
val ls = List(1, 2, 3, 4, 5)
ls.filter(_ % 2 == 0).sum
编辑:基于位置:
ls.indices.filter(_ % 2 == 0).map(ls(_)).sum
答案 1 :(得分:4)
zipWithIndex
可用于使用索引压缩List(1,3,1,3)
并返回List
个元组,这些元组可以针对偶数索引进行过滤,映射以获取值,然后求和。
scala> List(1,3,1,3).zipWithIndex
res0: List[(Int, Int)] = List((1,0),(3,1), (1,2), (3,3))
List(1,3,1,3).zipWithIndex.filter(_._2 % 2 == 0).map(_._1).sum
res1: Int = 2
答案 2 :(得分:3)
其他解决方案明确使用了元素的索引。
另一种方法是将组分为长度为2的子列表,并取每个子元素的第一个元素:
scala> List(1, 3, 1, 3).grouped(2).map(_.head).sum
res0: Int = 2
(head
应该可以安全使用,因为grouped
不应该返回空列表。)
答案 3 :(得分:2)
List(1,3,1,3).zipWithIndex.foldLeft(0) { (res, t) =>
if (t._2%2 == 0)
t._1 + res
else
res
}
zipWithIndex
为列表中的每个元素创建元素的元组及其在列表中的索引,然后您只需要折叠并根据索引返回结果或结果+当前项。
答案 4 :(得分:2)
List.sliding函数非常方便:
List(1,2,3,4).drop(1).sliding(1,2).flatten.sum
答案 5 :(得分:1)
val ls = List(1,2,3,4,5)
ls.foldLeft(0)((sum,elem) => if(elem%2==0) sum+elem else sum)
使用collect
或map
可以通过多种方式表达,但它们都会构建内部列表。例如:
ls.collect{
case n:Int if(n%2==0) => n
case n:Int => 0
}.sum
foldLeft
应该是最快的。
答案 6 :(得分:1)
嗯。这听起来像性能是一个问题,所以我跳过拉链和折叠,并采用尾递归解决方案:
def f( nums:List[Int] ) = {
def loop( nums:List[Int], soFar:Int ):Int = nums match {
case x::_::rest => loop( rest, soFar+x )
case x::rest => soFar + x
case _ => soFar
}
loop(nums,0)
}
答案 7 :(得分:0)
要对列表的偶数元素求和而不先创建中间列表(为了提高性能和内存效率),您可以这样做:
val x = List(1, 11, 2, 22, 3, 33)
val result = x.foldLeft((0,0))((p,e) => if ((p._1)%2==0) (p._1+1, p._2) else (p._1+1, p._2+e))._2
//> result : Int = 66
" P"是Tuple2 [Int,Int],其中第一个元素是位置索引,第二个元素是累积和。如果位置索引是偶数,它将返回一个带有下一个索引的新元组并累积" e"。如果位置索引是奇数,它将返回一个带有下一个索引的新元组,但不会累积" e"。
要对列表中奇数编号的元素求和,请执行以下操作:
val x = List(1, 11, 2, 22, 3, 33)
val result = x.foldLeft((0,0))((p,e) => if ((p._1)%2==0) (p._1+1, p._2+e) else (p._1+1, p._2))._2
//> result : Int = 6
答案 8 :(得分:0)
除了上述解决方案,您还可以使用
List(1,2,3,4,5).zipWithIndex.filter(_._2 % 2 == 0).foldLeft(0)( (sum,ele) => {sum+ele._1} );
res6: Int = 9
答案 9 :(得分:0)
List(1,3,1,3).foldLeft(0)((a, b)=> if(Math.abs(b%2) == 1)a+b else a)