1

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?

2 Answers 2

2

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.

Sign up to request clarification or add additional context in comments.

2 Comments

Thanks, it worked pretty well, except for one thing. The yield is returning a Vector instead of a Seq. Is it possible to make it return a Seq?
You can try for (i <- (1 to order.Quantity).toSeq) yield
2

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
    }
  } 
}

2 Comments

Is it possible to have the first approach you suggested while still having an iterative variable similar to the i in the normal for?
Yup, just replace the underscore (_) with an i. I just used an underscore because the index wasn't being referenced anywhere. I'll update my answer.

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.