listfunctionscalafunctional-programminglistbuffer

Update the values of a list with their absolute values


Newbie to scala.

I am trying to make this code to work for a few hours now . It is intended to update the List[Int](list of integers) with absolute values of the integers. Took a long time to figure out that List is immutable, so found that ListBuffer can be the saviour, but eventually in returning it back into the List form is seeing some issue i guess.

def f (arr:List[Int]) : List[Int] =
{
  val list = new scala.collection.mutable.ListBuffer[Int]();
  val len = arr.length;
  for ( i <- 0 to len)
  {
    if(arr(i) < 0)
    {

      list.append((-1)*arr(i)) ;
    }
    else
    {
      list.append(arr(i));
    }
  }

  return list.toList;

}

which is giving this error:

java.lang.IndexOutOfBoundsException: 12
at scala.collection.LinearSeqOptimized$class.apply(LinearSeqOptimized.scala:52)
at scala.collection.immutable.List.apply(List.scala:84)
at Solution$.f(Solution.scala:7)
at Solution$delayedInit$body.apply(Solution.scala:23)
at scala.Function0$class.apply$mcV$sp(Function0.scala:40)
at scala.runtime.AbstractFunction0.apply$mcV$sp(AbstractFunction0.scala:12)
at scala.App$$anonfun$main$1.apply(App.scala:71)
at scala.App$$anonfun$main$1.apply(App.scala:7...

Not getting what's wrong here.


Solution

  • The best way is to use Scala functions like @senia suggested in comments. For example:

    val res = list map math.abs
    

    But if you want to fix your code just replace to with until. You are getting off by one error:

    def f (arr:List[Int]) : List[Int] =
    {
    val list = new scala.collection.mutable.ListBuffer[Int]();
    val len = arr.length;
    for ( i <- 0 until len)
    {
        if(arr(i) < 0)
        {
    
            list.append((-1)*arr(i)) ;
        }
        else
        {
            list.append(arr(i));
        }
    }
    
    return list.toList;
    
    }
    

    Here is the difference between until and to:

    1 to 3
    // Range(1, 2, 3)
    
    1 until 3
    // Range(1, 2)
    

    You can also remove return, ; and even braces { used with if/else.