0

I have two arrays of same length

 import scala.util.Random
 val length = 10
 val x = 60 // Selection percentage
 val rnd = new Random
 var arrayOne =  Array.fill(length)(rnd .nextInt(100))
 arrayOne: Array[Int] = Array(8, 77, 11, 19, 17, 73, 5, 18, 45, 69)

 val arrayTwo =  Array.fill(length)(rnd .nextInt(100))
 arrayTwo: Array[Int] = Array(96, 21, 85, 70, 28, 5, 31, 56, 27, 76)

I can select first x percent element from arrayTwo and those selected elements can replace first x percent elements of arrayOne in the following way.

arrayOne = arrayTwo.take((length * x / 100).toInt) ++ arrayOne.drop((length * x / 100).toInt)
arrayOne: Array[Int] = Array(96, 21, 85, 70, 28, 5, 5, 18, 45, 69)

Now I want to select random x percent elements from arrayTwo and that selected elements will replace random x percent elements of arrayOne. How can I do this?

Asif
  • 763
  • 8
  • 18

2 Answers2

2

You can exchange every item with a probability x:

val x = 60D
val exchanged = arrayOne.indices
  .map(x => if(math.random > x / 100) arrayOne(x) else arrayTwo(x))

But that way you have no guarantee that (length * x / 100).toInt elements will be from arrayTwo. To achieve that I would go for iterative / recursive algorithm, where I'd pick random index until I have as much as I want.

Andronicus
  • 25,419
  • 17
  • 47
  • 88
2

You can do it via Random.shuffle:

scala> val randSet = Random.shuffle(arrayOne.indices.toBuffer).take((arrayOne.length * x / 100).toInt).toSet
randSet: scala.collection.immutable.Set[Int] = HashSet(0, 6, 9, 3, 8, 4)

scala> val randMerged = arrayOne.indices.map(i => if(randSet(i)) arrayTwo(i) else arrayOne(i))
randMerged: IndexedSeq[Int] = Vector(96, 77, 11, 70, 28, 73, 31, 18, 27, 76)

The randSet will take x percent indices randomly.

If you do not care the number's position, there is a simple one:

scala> val size = (arrayOne.length * x / 100).toInt
size: Int = 6

scala> Random.shuffle(arrayTwo).take(size) ++ Random.shuffle(arrayOne).drop(size)
res11: scala.collection.mutable.ArraySeq[Int] = ArraySeq(76, 85, 28, 56, 21, 27, 69, 45, 17, 77)
esse
  • 1,415
  • 5
  • 10