Common shuffle/shuffled with the specified random source
KT-17261, KT-9010
This commit is contained in:
@@ -6,7 +6,7 @@
|
|||||||
package kotlin.collections
|
package kotlin.collections
|
||||||
|
|
||||||
import kotlin.comparisons.naturalOrder
|
import kotlin.comparisons.naturalOrder
|
||||||
import kotlin.math.floor
|
import kotlin.random.Random
|
||||||
|
|
||||||
/** Returns the array if it's not `null`, or an empty array otherwise. */
|
/** Returns the array if it's not `null`, or an empty array otherwise. */
|
||||||
@kotlin.internal.InlineOnly
|
@kotlin.internal.InlineOnly
|
||||||
@@ -87,16 +87,7 @@ public actual fun <T> MutableList<T>.fill(value: T): Unit {
|
|||||||
* See: https://en.wikipedia.org/wiki/Fisher%E2%80%93Yates_shuffle#The_modern_algorithm
|
* See: https://en.wikipedia.org/wiki/Fisher%E2%80%93Yates_shuffle#The_modern_algorithm
|
||||||
*/
|
*/
|
||||||
@SinceKotlin("1.2")
|
@SinceKotlin("1.2")
|
||||||
public actual fun <T> MutableList<T>.shuffle(): Unit {
|
public actual fun <T> MutableList<T>.shuffle(): Unit = shuffle(Random)
|
||||||
for (i in lastIndex downTo 1) {
|
|
||||||
val j = rand(i + 1)
|
|
||||||
val copy = this[i]
|
|
||||||
this[i] = this[j]
|
|
||||||
this[j] = copy
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
private fun rand(upperBound: Int) = floor(kotlin.js.Math.random() * upperBound).toInt()
|
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Returns a new list with the elements of this list randomly shuffled.
|
* Returns a new list with the elements of this list randomly shuffled.
|
||||||
|
|||||||
@@ -8,6 +8,8 @@
|
|||||||
|
|
||||||
package kotlin.collections
|
package kotlin.collections
|
||||||
|
|
||||||
|
import kotlin.random.Random
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Removes a single instance of the specified element from this
|
* Removes a single instance of the specified element from this
|
||||||
* collection, if it is present.
|
* collection, if it is present.
|
||||||
@@ -259,3 +261,26 @@ private fun MutableCollection<*>.retainNothing(): Boolean {
|
|||||||
clear()
|
clear()
|
||||||
return result
|
return result
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Randomly shuffles elements in this mutable list using the specified [random] instance as the source of randomness.
|
||||||
|
*
|
||||||
|
* See: https://en.wikipedia.org/wiki/Fisher%E2%80%93Yates_shuffle#The_modern_algorithm
|
||||||
|
*/
|
||||||
|
@SinceKotlin("1.3")
|
||||||
|
public fun <T> MutableList<T>.shuffle(random: Random): Unit {
|
||||||
|
for (i in lastIndex downTo 1) {
|
||||||
|
val j = random.nextInt(i + 1)
|
||||||
|
val copy = this[i]
|
||||||
|
this[i] = this[j]
|
||||||
|
this[j] = copy
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Returns a new list with the elements of this list randomly shuffled
|
||||||
|
* using the specified [random] instance as the source of randomness.
|
||||||
|
*/
|
||||||
|
@SinceKotlin("1.3")
|
||||||
|
public fun <T> Iterable<T>.shuffled(random: Random): List<T> = toMutableList().apply { shuffle(random) }
|
||||||
|
|
||||||
|
|||||||
@@ -5,6 +5,7 @@
|
|||||||
|
|
||||||
package test.collections
|
package test.collections
|
||||||
|
|
||||||
|
import kotlin.random.Random
|
||||||
import kotlin.test.*
|
import kotlin.test.*
|
||||||
|
|
||||||
|
|
||||||
@@ -114,4 +115,16 @@ class MutableCollectionTest {
|
|||||||
assertEquals(list.size, shuffled.distinct().size)
|
assertEquals(list.size, shuffled.distinct().size)
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@Test fun shuffledPredictably() {
|
||||||
|
val list = List(10) { it }
|
||||||
|
val shuffled1 = list.shuffled(Random(1))
|
||||||
|
val shuffled11 = list.shuffled(Random(1))
|
||||||
|
|
||||||
|
assertEquals(shuffled1, shuffled11)
|
||||||
|
assertEquals("[1, 4, 0, 6, 2, 8, 9, 7, 3, 5]", shuffled1.toString())
|
||||||
|
|
||||||
|
val shuffled2 = list.shuffled(Random(42))
|
||||||
|
assertEquals("[5, 0, 4, 9, 2, 8, 1, 7, 6, 3]", shuffled2.toString())
|
||||||
|
}
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|||||||
+2
@@ -2343,8 +2343,10 @@ public final class kotlin/collections/CollectionsKt {
|
|||||||
public static final fun retainAll (Ljava/util/List;Lkotlin/jvm/functions/Function1;)Z
|
public static final fun retainAll (Ljava/util/List;Lkotlin/jvm/functions/Function1;)Z
|
||||||
public static final fun reverse (Ljava/util/List;)V
|
public static final fun reverse (Ljava/util/List;)V
|
||||||
public static final fun reversed (Ljava/lang/Iterable;)Ljava/util/List;
|
public static final fun reversed (Ljava/lang/Iterable;)Ljava/util/List;
|
||||||
|
public static final fun shuffle (Ljava/util/List;Lkotlin/random/Random;)V
|
||||||
public static final fun shuffled (Ljava/lang/Iterable;)Ljava/util/List;
|
public static final fun shuffled (Ljava/lang/Iterable;)Ljava/util/List;
|
||||||
public static final fun shuffled (Ljava/lang/Iterable;Ljava/util/Random;)Ljava/util/List;
|
public static final fun shuffled (Ljava/lang/Iterable;Ljava/util/Random;)Ljava/util/List;
|
||||||
|
public static final fun shuffled (Ljava/lang/Iterable;Lkotlin/random/Random;)Ljava/util/List;
|
||||||
public static final fun single (Ljava/lang/Iterable;)Ljava/lang/Object;
|
public static final fun single (Ljava/lang/Iterable;)Ljava/lang/Object;
|
||||||
public static final fun single (Ljava/lang/Iterable;Lkotlin/jvm/functions/Function1;)Ljava/lang/Object;
|
public static final fun single (Ljava/lang/Iterable;Lkotlin/jvm/functions/Function1;)Ljava/lang/Object;
|
||||||
public static final fun single (Ljava/util/List;)Ljava/lang/Object;
|
public static final fun single (Ljava/util/List;)Ljava/lang/Object;
|
||||||
|
|||||||
Reference in New Issue
Block a user