Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

How to sum adjacent elements in scala

I want to sum adjacent elements in scala and I'm not sure how to deal with the last element.

So I have a list:

val x = List(1,2,3,4)

And I want to sum adjacent elements using indices and map:

val size = x.indices.size
val y = x.indices.map(i => 
    if (i < size - 1)
       x(i) + x(i+1))

The problem is that this approach creates an AnyVal elemnt at the end:

res1: scala.collection.immutable.IndexedSeq[AnyVal] = Vector(3, 5, 7, ())

and if I try to sum the elements or another numeric method of the collection, it doesn't work:

error: could not find implicit value for parameter num: Numeric[AnyVal]

I tried to filter out the element using:

y diff List(Unit) or y diff List(AnyVal)

but it doesn't work.

Is there a better approach in scala to do this type of adjacent sum without using a foor loop?

like image 353
user1917028 Avatar asked Mar 25 '15 15:03

user1917028


3 Answers

For a more functional solution, you can use sliding to group the elements together in twos (or any number of them), then map to their sum.

scala> List(1, 2, 3, 4).sliding(2).map(_.sum).toList
res80: List[Int] = List(3, 5, 7)

What sliding(2) will do is create an intermediate iterator of lists like this:

Iterator(
    List(1, 2),
    List(2, 3),
    List(3, 4)
)

So when we chain map(_.sum), we will map each inner List to it's own sum. toList will convert the Iterator back into a List.

like image 124
Michael Zajac Avatar answered Nov 14 '22 13:11

Michael Zajac


You can try pattern matching and tail recursion also.

import scala.annotation.tailrec
@tailrec
def f(l:List[Int],r :List[Int]=Nil):List[Int] = {
l match {
    case x :: xs :: xss => 
    f(l.tail, r :+ (x + xs))
    case _ => r
}
}



scala> f(List(1,2,3,4))
res4: List[Int] = List(3, 5, 7)
like image 33
curious Avatar answered Nov 14 '22 12:11

curious


With a for comprehension by zipping two lists, the second with the first item dropped,

for ( (a,b) <- x zip x.drop(1) ) yield a+b

which results in

List(3, 5, 7)
like image 1
elm Avatar answered Nov 14 '22 13:11

elm