Sayat Satybald
Sayat Satybald

Reputation: 6580

Functional Creating a list based on values in Scala

I have a task to traverse a sequence of tuples and based on last value in the tuple make 1 or more copies of a case class Item. I can solve this task with foreach and Mutable List. As I'm learning FP and Scala collections could it be done more functional way with immutable collections and high order functions in Scala?

For example, input:

List[("A", 2), ("B", 3), ...]

Output:

List[Item("A"), Item("A"), Item("B"),Item("B"),Item("B"), ...]

Upvotes: 2

Views: 94

Answers (2)

elm
elm

Reputation: 20405

Using flatten for case class Item(v: String) as follows

myList.map{ case(s,n) => List.fill(n)(Item(s)) }.flatten

Also with a for comprehension like this,

for ( (s,n) <- myList ; l <- List.fill(n)(Item(s)) ) yield l

which is syntax sugar for a call to flatMap.

In addition to List.fill consider List.tabulate for initialising lists, for instance in this way,

for ( (s,n) <- myList ; l <- List.tabulate(n)(_ => Item(s)) ) yield l

Upvotes: 1

Brian
Brian

Reputation: 20285

For each tuple flatMap using List.fill[A](n: Int)(elem: ⇒ A) which produces a List of elem n times.

scala> val xs = List(("A", 2), ("B", 3), ("C", 4))
xs: List[(String, Int)] = List((A,2), (B,3), (C,4))

scala> case class Item(s: String)
defined class Item

scala> xs.flatMap(x => List.fill(x._2)(Item(x._1)))
res2: List[Item] = List(Item(A), Item(A), Item(B), Item(B), Item(B), Item(C), Item(C), Item(C), Item(C))

Upvotes: 5

Related Questions