Phil
Phil

Reputation: 3562

Building a list in Scala

Why is it so hard to build a list in Scala? I know many other languages, and I have never had such a hard time trying to figure out a very simple use case... I spent over an hour on something that should take only 1 minute to implement. I'm a bit upset at this point which is why I'm asking for help now

Problem: What I'm trying to do is pass in an array of integers and return an array of the cubes of the odd numbers.

Constraints: I have to use Lists, I have to use a for loop

This is what I have so far:

    def cubes(a1: List[Int]): List[Int] = {
        var a2 = List[Int]()

        for(i <- 0 to a1.size-1){
            if(a1(i)%2 != 0) a2 :+ a1(i) * a1(i) * a1(i)
        }

        //If I try to print out the first element I get an error
        println(a2(0))
    }

    cubes(List(1, 2, 3, 4, 5, 6, 7))

This is the error

list1.scala:15: error: type mismatch;
 found   : Unit
 required: List[Int]
        println(a2(0))
               ^

Question: How can I refactor my code so that I can build a List given my constraints

Upvotes: 0

Views: 98

Answers (2)

Shaido
Shaido

Reputation: 28422

Instead of using a var you can take advantage of that a list can be returned from a for-comprehension using the yield keyword.

Example that assigns the result to a list variable and returns it:

def cubes(a: List[Int]): List[Int] = {
  val cubesList = for (item <- a if item % 2 != 0) yield {
    Math.pow(item, 3).toInt
  }
  cubesList  //return the list created by the loop
}

Testing it:

scala> cubes(List(1,2,3,4,5)) foreach println
1
27
125

The above code can be shortened by returning the result of the for-comprehension directly. Then you can also omit the curly braces:

def cubes(a: List[Int]): List[Int] = 
  for (item <- a if item % 2 != 0) 
  yield Math.pow(item, 3).toInt

Upvotes: 1

Phil
Phil

Reputation: 3562

The solution is to use a ListBuffer and convert it to a list before returning. Lists are immutable so we have to use a list buffer.

Also the error I was getting was because the return type is List[Int] but I wasn't returning anything and I was trying to print which I'm guessing returns some type of Unit

I'm still very upset it took this long to figure out... Oh well

Here's the solution:

   import scala.collection.mutable.ListBuffer

    def cubes(a1: List[Int]): List[Int] = {
        var cubes = new ListBuffer[Int]()

        for (item <- a1 if item % 2 != 0) yield {
            cubes += Math.pow(item, 3).toInt
        }

        val cubesList = cubes.toList

        return cubesList
    }

    println(cubes(List(1, 2, 3, 4, 5, 6, 7)))
    println(cubes(List(3, 5, 6, 7, 11)))

Upvotes: 0

Related Questions