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?

2 Answers 2

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.

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

4 Comments

can you share your iterative approach?
I set x = 60 , and your code is returning arrayOne every time.
@Asif yes, because you're making it an Int
@Asif iterative approach is easy to find in other languages, in Scala this will not be that different. Here is an example: stackoverflow.com/questions/19269545/…
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)

2 Comments

shuffle is expensive operation
@Asif It's a O(n) time complexity, you can not do better than O(n) in any way of your problem.

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.