0

我试图总结偶数项目,我去制作元组并对其中的第一个值求和,但它创建了很多立即丢弃的对象。

也许有人可以建议更轻量级的解决方案(也许使用fold)?

编辑:我的意思是偶数位置的数字

测试用例:

List(1,3,1,3).foldLeft(x)(magic) === 2
4

10 回答 10

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
于 2013-06-12T06:48:50.537 回答
4
val ls = List(1, 2, 3, 4, 5)
ls.filter(_ % 2 == 0).sum

编辑:基于位置:

ls.indices.filter(_ % 2 == 0).map(ls(_)).sum
于 2013-06-12T06:36:52.550 回答
3

其他解决方案已明确使用元素的索引。

另一种方法是分组为长度为 2 的子列表,并获取每个子列表的第一个元素:

scala> List(1, 3, 1, 3).grouped(2).map(_.head).sum
res0: Int = 2

head应该可以安全使用,因为grouped不应该返回空列表。)

于 2013-06-12T07:23:20.903 回答
2
List(1,3,1,3).zipWithIndex.foldLeft(0) { (res, t) =>
  if (t._2%2 == 0)
    t._1 + res
  else
    res
}

zipWithIndex为列表中的每个元素创建一个元素的元组及其在列表中的索引,然后您只需折叠并根据索引返回结果或结果+当前项目。

于 2013-06-12T06:53:24.880 回答
2

List.sliding 函数在这里非常方便:

List(1,2,3,4).drop(1).sliding(1,2).flatten.sum
于 2015-10-28T02:35:46.167 回答
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)
}
于 2013-06-12T18:26:56.417 回答
1
val ls = List(1,2,3,4,5)
ls.foldLeft(0)((sum,elem) => if(elem%2==0) sum+elem else sum)

有多种方法可以使用collector map,但它们都将构建一个内部列表。例如:

ls.collect{
  case n:Int if(n%2==0) => n
  case n:Int => 0
}.sum

foldLeft应该是最快的。

于 2013-06-12T06:31:05.677 回答
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
于 2015-06-17T00:02:28.107 回答
0

List(1,3,1,3).foldLeft(0)((a, b)=> if(Math.abs(b%2) == 1)a+b else a)

于 2016-05-23T07:02:22.360 回答
0

除了上述解决方案,您还可以使用

List(1,2,3,4,5).zipWithIndex.filter(_._2 % 2 == 0).foldLeft(0)( (sum,ele) => {sum+ele._1} );

res6: Int = 9
于 2016-03-31T05:34:27.733 回答