偶数のアイテムを合計しようとしていて、タプルを作成してそれらの最初の値を合計しようとしましたが、すぐに破棄されるオブジェクトがたくさん作成されています。
たぶん、誰かがより軽量なソリューションを提案できますか(おそらくfold
)?
編集:偶数位置の数字を意味しました
テストケース:
List(1,3,1,3).foldLeft(x)(magic) === 2
偶数のアイテムを合計しようとしていて、タプルを作成してそれらの最初の値を合計しようとしましたが、すぐに破棄されるオブジェクトがたくさん作成されています。
たぶん、誰かがより軽量なソリューションを提案できますか(おそらくfold
)?
編集:偶数位置の数字を意味しました
テストケース:
List(1,3,1,3).foldLeft(x)(magic) === 2
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
ここでは List.sliding 関数が非常に便利です。
List(1,2,3,4).drop(1).sliding(1,2).flatten.sum
List(1,3,1,3).zipWithIndex.foldLeft(0) { (res, t) =>
if (t._2%2 == 0)
t._1 + res
else
res
}
zipWithIndex
リスト内の各要素に対して、リスト内の要素とそのインデックスのタプルを作成し、折り畳む必要があり、インデックスに応じて、結果または結果 + 現在のアイテムを返します。
うーん。ここではパフォーマンスが懸念されるように思われるので、zip と折り畳みをスキップして、末尾再帰ソリューションを使用します。
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)
}
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
最速のはずです。
List(1,3,1,3).foldLeft(0)((a, b)=> if(Math.abs(b%2) == 1)a+b else a)
最初に中間リストを作成せずにリストの偶数番号の要素を合計するには (パフォーマンスとメモリ効率のために)、次のようにします。
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] で、最初の要素は位置インデックスで、2 番目の要素は累積和です。位置インデックスが偶数の場合、次のインデックスと累積された "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