Reputation: 2851
Given a List[Int]
l, how can I insert randomly a new element elem
into the List[Int]
l?
def randomInsert(l: List[Int], elem: Int): List[Int] = ???
Upvotes: 1
Views: 128
Reputation: 2851
This can be done by first, picking a random index into the list and then inserting the new element at that index. Also this can be done in a generic way:
import scala.util.Random
def randomInsert[A](l: List[A], elem: A): List[A] = {
val random = new Random
val randomIndex = random.nextInt(l.length + 1)
l.patch(randomIndex, List(elem), 0)
}
Usage:
scala>randomInsert(List(1,2,3,4,5),100)
res2: List[Int] = List(1, 2, 3, 4, 5, 100)
scala>randomInsert(List(1,2,3,4,5),100)
res3: List[Int] = List(100, 1, 2, 3, 4, 5)
scala>randomInsert(List(1,2,3,4,5),100)
res4: List[Int] = List(1, 2, 100, 3, 4, 5)
We can use this method to add recursively several elements:
import scala.util.Random
import scala.annotation.tailrec
def randomInsert[A](l: List[A], elem: A, elems: A*): List[A] = {
val random = new Random
@tailrec
def loop(elemToInsert: List[A], acc: List[A]): List[A] =
elemToInsert match {
case Nil => acc
case head :: tail =>
val randomIndex = random.nextInt(acc.length + 1)
loop(tail, acc.patch(randomIndex, List(head), 0))
}
loop(elem :: elems.toList, l)
}
Usage:
scala>randomInsert(List(1,2,3,4,5),100,101,102)
res10: List[Int] = List(1, 2, 101, 3, 4, 5, 100, 102)
scala>randomInsert(List(1,2,3,4,5),100,101,102)
res11: List[Int] = List(1, 2, 102, 100, 101, 3, 4, 5)
scala>randomInsert(List(1,2,3,4,5),100,101,102)
res12: List[Int] = List(1, 2, 3, 4, 100, 5, 102, 101)
Edit: As per comment, an more efficient way to do this is to join both list and to shuffle the combined one - note than by doing so you may lose the original order of the list:
import scala.util.Random
def randomInsert[A](l: List[A], elem: A, elems: A*): List[A] = {
Random.shuffle((elem :: elems.toList) reverse_::: l)
}
Upvotes: 3