问题
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.
回答1:
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
.
回答2:
Yet another version using a for
comprehension that avoids indexing,
def f (arr:List[Int]) : List[Int] =
{
val list = new scala.collection.mutable.ListBuffer[Int]();
for {
a <- arr
sign = if (a < 0) -1 else 1
} list.append(sign * a)
return list.toList;
}
As mentioned above, the return
may be omitted.
回答3:
You can try using case statements for more neat syntax :
def f(arr:List[Int]):List[Int] = {
val list = scala.collection.mutable.ListBuffer[Int]()
arr.foreach{
x =>
x match {
case _ if (x <0) => list+= (x*(-1))
case _ => list +=x
}
}
list.toList
}
回答4:
Looks like you were trying to solve the challenge from here. Probably you may want to use more functional approach with recursion and immutable List.
def f(arr: List[Int]): List[Int] = arr match {
case Nil => Nil
case x :: rest => java.lang.Math.abs(x) :: f(rest)
}
回答5:
Beginner friendly: this is how I wrote it
def f(arr: List[Int]) : List[Int] = {
var list = new scala.collection.mutable.ArrayBuffer[Int]();
// var len = arr.length;
for(i <-0 until arr.length) {
list.append( math.abs(arr(i)));
}
return list.toList; }
I haven't done any time complexity analysis but it's the most straightforward for beginners to understand. Also, it passes all the tests on hackerrank
回答6:
def f (arr: List[Int]) : List[Int] = {
arr.map {
case i if 0 > i => i * -1
case i => i
}
}
来源:https://stackoverflow.com/questions/21219993/update-the-values-of-a-list-with-their-absolute-values