Reputation: 6580
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
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
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