java - number - random kotlin
¿Cómo puedo obtener un número aleatorio en Kotlin? (19)
Para obtener un número Int aleatorio en Kotlin, use el siguiente método :
import java.util.concurrent.ThreadLocalRandom
fun randomInt(rangeFirstNum:Int, rangeLastNum:Int) {
val randomInteger = ThreadLocalRandom.current().nextInt(rangeFirstNum,rangeLastNum)
println(randomInteger)
}
fun main() {
randomInt(1,10)
}
// Result – random Int numbers from 1 to 9
Espero que esto ayude.
Un método genérico que puede devolver un entero aleatorio entre 2 parámetros como lo hace Ruby con
rand(0..n)
.
¿Cualquier sugerencia?
Kotlin> = 1.3, soporte multiplataforma para Aleatorio
A partir de 1.3, la biblioteca estándar proporcionó soporte multiplataforma para randoms, consulte @s1m0nw1 respuesta.
Kotlin <1.3 en JavaScript
Si está trabajando con Kotlin JavaScript y no tiene acceso a
java.util.Random
, lo siguiente funcionará:
fun IntRange.random() = (Math.random() * ((endInclusive + 1) - start) + start).toInt()
Usado así:
// will return an `Int` between 0 and 10 (incl.)
(0..10).random()
A partir de kotlin 1.2, podría escribir:
(1..3).shuffled().last()
Solo tenga en cuenta que es grande O (n), pero para una lista pequeña (especialmente de valores únicos) está bien: D
Ejemplos aleatorios en el rango [1, 10]
val random1 = (0..10).shuffled().last()
o utilizando Java Random
val random2 = Random().nextInt(10) + 1
En Kotlin 1.3 puedes hacerlo como
val number = Random.nextInt(limit)
Genere un entero aleatorio entre
from
(inclusive) y
to
(exclusive)
import java.util.Random
val random = Random()
fun rand(from: Int, to: Int) : Int {
return random.nextInt(to - from) + from
}
Kotlin standard lib no proporciona API de generador de números aleatorios. Si no está en un proyecto multiplataforma, es mejor usar la API de plataforma (todas las otras respuestas de la pregunta hablan sobre esta solución) .
Pero si se encuentra en un contexto multiplataforma, la mejor solución es implementar aleatoriamente usted mismo en Kotlin puro para compartir el mismo generador de números aleatorios entre plataformas. Es más simple para desarrolladores y pruebas.
Para responder a este problema en mi proyecto personal, implemento un
generador congruencia lineal lineal
Kotlin puro.
LCG es el algoritmo utilizado por
java.util.Random
.
Siga este enlace si desea usarlo:
https://gist.github.com/11e5ddb567786af0ed1ae4d7f57441d4
Mi propósito de implementación
nextInt(range: IntRange)
para usted;).
Tenga cuidado con mi propósito, LCG es bueno para la mayoría de los casos de uso (simulación, juegos, etc.) pero no es adecuado para el uso criptográfico debido a la previsibilidad de este método.
Mi sugerencia sería una función de
extension
en
IntRange
para crear randoms como este:
(0..10).random()
TL; DR Kotlin> = 1.3, uno aleatorio para todas las plataformas
A partir de 1.3, Kotlin viene con su propio generador aleatorio multiplataforma. Se describe en este KEEP . La extensión que se describe a continuación ahora es parte de la biblioteca estándar de Kotlin , simplemente úsela así:
val rnds = (0..10).random()
Kotlin <1.3
Antes de 1.3, en la JVM usamos
Random
o incluso
ThreadLocalRandom
si estamos en JDK> 1.6.
fun IntRange.random() =
Random().nextInt((endInclusive + 1) - start) + start
Usado así:
// will return an `Int` between 0 and 10 (incl.)
(0..10).random()
Si desea que la función solo devuelva
1, 2, ..., 9
(
10
no incluidos), use un rango construido con
until
:
(0 until 10).random()
Si está trabajando con JDK> 1.6, use
ThreadLocalRandom.current()
lugar de
Random()
.
KotlinJs y otras variaciones
Para kotlinjs y otros casos de uso que no permiten el uso de
java.util.Random
, vea
esta alternativa
.
Además, vea esta answer para ver variaciones de mi sugerencia. También incluye una función de extensión para caracteres aleatorios.
No existe un método estándar que haga esto, pero puede crear fácilmente el suyo usando
Math.random()
o la clase
java.util.Random
.
Aquí hay un ejemplo usando el método
Math.random()
:
fun random(n: Int) = (Math.random() * n).toInt()
fun random(from: Int, to: Int) = (Math.random() * (to - from) + from).toInt()
fun random(pair: Pair<Int, Int>) = random(pair.first, pair.second)
fun main(args: Array<String>) {
val n = 10
val rand1 = random(n)
val rand2 = random(5, n)
val rand3 = random(5 to n)
println(List(10) { random(n) })
println(List(10) { random(5 to n) })
}
Esta es una salida de muestra:
[9, 8, 1, 7, 5, 6, 9, 8, 1, 9]
[5, 8, 9, 7, 6, 6, 8, 6, 7, 9]
Otra forma de implementar la respuesta de s1m0nw1 sería acceder a través de una variable. No es que sea más eficiente, pero le ahorra tener que escribir ().
val ClosedRange<Int>.random: Int
get() = Random().nextInt((endInclusive + 1) - start) + start
Y ahora se puede acceder como tal
(1..10).random
Partiendo de la excelente respuesta de @s1m0nw1 , hice los siguientes cambios.
- (0..n) implica inclusivo en Kotlin
- (0 hasta n) implica exclusivo en Kotlin
- Use un objeto singleton para la instancia aleatoria (opcional)
Código:
private object RandomRangeSingleton : Random()
fun ClosedRange<Int>.random() = RandomRangeSingleton.nextInt((endInclusive + 1) - start) + start
Caso de prueba:
fun testRandom() {
Assert.assertTrue(
(0..1000).all {
(0..5).contains((0..5).random())
}
)
Assert.assertTrue(
(0..1000).all {
(0..4).contains((0 until 5).random())
}
)
Assert.assertFalse(
(0..1000).all {
(0..4).contains((0..5).random())
}
)
}
Podría crear una función de extensión:
infix fun ClosedRange<Float>.step(step: Float): Iterable<Float> {
require(start.isFinite())
require(endInclusive.isFinite())
require(step.round() > 0.0) { "Step must be positive, was: $step." }
require(start != endInclusive) { "Start and endInclusive must not be the same"}
if (endInclusive > start) {
return generateSequence(start) { previous ->
if (previous == Float.POSITIVE_INFINITY) return@generateSequence null
val next = previous + step.round()
if (next > endInclusive) null else next.round()
}.asIterable()
}
return generateSequence(start) { previous ->
if (previous == Float.NEGATIVE_INFINITY) return@generateSequence null
val next = previous - step.round()
if (next < endInclusive) null else next.round()
}.asIterable()
}
Valor de flotación redonda:
fun Float.round(decimals: Int = DIGITS): Float {
var multiplier = 1.0f
repeat(decimals) { multiplier *= 10 }
return round(this * multiplier) / multiplier
}
Uso del método:
(0.0f .. 1.0f).step(.1f).forEach { System.out.println("value: $it") }
Salida:
valor: 0.0 valor: 0.1 valor: 0.2 valor: 0.3 valor: 0.4 valor: 0.5 valor: 0.6 valor: 0.7 valor: 0.8 valor: 0.9 valor: 1.0
Primero, necesitas un RNG.
En Kotlin actualmente necesitas usar los específicos de la plataforma (no hay un Kotlin integrado en uno).
Para la JVM es
Random
.
Deberá crear una instancia y luego llamar a
random.nextInt(n)
.
Puede crear una
función de extensión
similar a
java.util.Random.nextInt(int)
pero una que toma un
IntRange
lugar de un
Int
para su límite:
fun Random.nextInt(range: IntRange): Int {
return range.start + nextInt(range.last - range.start)
}
Ahora puede usar esto con cualquier instancia
Random
:
val random = Random()
println(random.nextInt(5..9)) // prints 5, 6, 7, or 8
Si no desea tener que administrar su propia instancia
Random
, puede definir un método conveniente utilizando, por ejemplo,
ThreadLocalRandom.current()
:
fun rand(range: IntRange): Int {
return ThreadLocalRandom.current().nextInt(range)
}
Ahora puede obtener un número entero aleatorio como lo haría en Ruby sin tener que declarar primero una instancia
Random
:
rand(5..9) // returns 5, 6, 7, or 8
Si los números que desea elegir no son consecutivos, puede usar
random()
.
Uso:
val list = listOf(3, 1, 4, 5)
val number = list.random()
Devuelve uno de los números que están en la lista.
Usando una función de nivel superior, puede lograr exactamente la misma sintaxis de llamada que en Ruby (como lo desee):
fun rand(s: Int, e: Int) = Random.nextInt(s, e + 1)
Uso:
rand(1, 3) // returns either 1, 2 or 3
ser súper tonto))
fun rnd_int(min: Int, max: Int): Int {
var max = max
max -= min
return (Math.random() * ++max).toInt() + min
}
Posible variación a mi extension para caracteres aleatorios
Para obtener caracteres aleatorios, puede definir una función de extensión como esta
fun ClosedRange<Char>.random(): Char =
(Random().nextInt(endInclusive.toInt() + 1 - start.toInt()) + start.toInt()).toChar()
// will return a `Char` between A and Z (incl.)
(''A''..''Z'').random()
Si está trabajando con JDK> 1.6, use
IntRange
lugar de
Random()
.
Para kotlinjs y otros casos de uso que no permiten el uso de
java.util.Random
,
until
será de ayuda.
Kotlin> = 1.3 soporte multiplataforma para Aleatorio
A partir de 1.3, Kotlin viene con su propio generador aleatorio multiplataforma. Se describe en este KEEP . Ahora puede usar directamente la extensión como parte de la biblioteca estándar de Kotlin sin definirla:
(''a''..''b'').random()