João Pinto
João Pinto

Reputation: 1998

How to use map with for loop inside in Scala?

I need to create a list inside a for loop and I am having trouble doing it.

I used to have this code which works fine:

val tasksSchedules = orders.map (order => {                
    // Creates list of TaskSchedules
    order.Product.Tasks.map(task => {                     
        // Create TaskSchedule
    })        
})

However a new requirement came up where I now need to repeat the creation of the list of TaskSchedule based on a Quantity. I now have the following code:

val tasksSchedules = orders.map (order => {
    // Repeats creation of TaskSchedules as many times as the value of Quantity
    // Creation of list is lost with this for.
    for (i <- 1 to order.Quantity) {
        // Creates list of TaskSchedules
        order.Product.Tasks.map(task => {                     
            // Create TaskSchedule
        })
    }    
})

Without the for loop everything works seamlessly. However, with the for loop no list is created which I think is to be expected. Essentially, I need a for loop construct that will enable me to iterate until a certain value and behave like the map function so I can also create a list.

Is there such a thing? Is this feasible?

Upvotes: 1

Views: 1252

Answers (2)

Jack Leow
Jack Leow

Reputation: 22497

For what it's worth, a for-comprehension is simply rewritten as map() calls. Instead of your current implementation (which is IMO, inconsistent), you could simply rewrite it using just map()s:

val tasksSchedules = orders.map { order =>
  // Repeats creation of TaskSchedules as many times as the value of Quantity
  // Creation of list is lost with this for.
  (1 to order.Quantity).toSeq.map { i =>
    // Creates list of TaskSchedules
    order.Product.Tasks.map { task =>
      // Create TaskSchedule
    }
  }
}

Or just for-comprehensions:

val tasksSchedules = for (order <- orders) yield {
  // Repeats creation of TaskSchedules as many times as the value of Quantity
  // Creation of list is lost with this for.
  for (i <- (1 to order.Quantity).toSeq) yield {
    // Creates list of TaskSchedules
    for (task <- order.Product.Tasks) yield {
      // Create TaskSchedule
    }
  } 
}

Upvotes: 2

Assaf Mendelson
Assaf Mendelson

Reputation: 13001

When you do a for loop, in order to generate a list you need to use the yield command:

val tasksSchedules = orders.map (order => {
  // Repeats creation of TaskSchedules as many times as the value of Quantity
  // Creation of list is lost with this for.
  for (i <- 1 to order.Quantity) yield {
      // Creates list of TaskSchedules
      order.Product.Tasks.map(task => {                     
          // Create TaskSchedule
      })
  }    

})

In this case it would give you a list of list of list.

If you just need a list of list then use flatmap instead of map.

Upvotes: 2

Related Questions