Comment puis-je obtenir un nombre aléatoire dans Kotlin?
Une méthode générique qui peut renvoyer un entier aléatoire entre 2 paramètres comme le fait ruby avec rand(0..n)
.
Une suggestion?
15 réponses
Kotlin
Je suggère d'utiliser la fonction extension {[14] } suivante sur IntRange :
fun IntRange.random() =
Random().nextInt((endInclusive + 1) - start) + start
Et utilisez-le comme ceci:
// will return an `Int` between 0 and 10 (incl.)
(0..10).random()
Si vous voulez que la fonction ne renvoie que 1, 2,..., 9 (10 exclusif), utiliser une gamme construite avec until
:
(0 until 10).random()
Si vous travaillez avec JDK > 1.6, l'utilisation ThreadLocalRandom.current()
au lieu de Random()
.
KotlinJs et autres variations
Pour kotlinjs et d'autres cas d'utilisation qui ne permettent l'utilisation de java.util.Random
, voir cette alternative.
Voir Aussi cette réponse pour les variations de ma suggestion. Il comprend également une fonction d'extension pour random Char
s.
Kotlin >= 1.3 multiplateforme Aléatoire
À partir de 1.3, Kotlin est livré avec son propre générateur aléatoire multiplateforme. Il est décrit dans ce GARDER. Vous pouvez maintenant faire ce qui suit (source):
Random.nextInt(0..10)
La fonction d'extension peut être simplifié à ce qui suit sur toutes les plateformes:
fun IntRange.random() = Random.nextInt(this)
Générer un entier aléatoire compris entre from
(inclus) et to
(exclusif)
import java.util.Random
val random = Random()
fun rand(from: Int, to: Int) : Int {
return random.nextInt(to - from) + from
}
À partir de Kotlin 1.2, vous pouvez écrire:
(1..3).shuffled().last()
Sachez simplement que c'est grand O (n), mais pour une petite liste (en particulier de valeurs uniques), c'est bien: D
, Vous pouvez créer un fonction d'extension semblable à java.util.Random.nextInt(int)
mais celui qui prend un IntRange
au lieu de Int
pour son lié:
fun Random.nextInt(range: IntRange): Int {
return range.start + nextInt(range.last - range.start)
}
Vous pouvez maintenant l'utiliser avec n'importe quel Random
exemple:
val random = Random()
println(random.nextInt(5..9)) // prints 5, 6, 7, or 8
Si vous ne voulez pas avoir à gérer votre propre Random
exemple, alors vous pouvez définir une méthode de convenance à l'aide, par exemple, ThreadLocalRandom.current()
:
fun rand(range: IntRange): Int {
return ThreadLocalRandom.current().nextInt(range)
}
Maintenant, vous pouvez obtenir un nombre entier aléatoire comme vous le feriez dans Ruby sans avoir à déclarez vous-même une instance Random
:
rand(5..9) // returns 5, 6, 7, or 8
Variation Possible de mon Autre réponse pour les caractères aléatoires
Afin d'obtenir des Char
aléatoires, vous pouvez définir une fonction d'extension comme ceci
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 vous travaillez avec JDK > 1.6, l'utilisation ThreadLocalRandom.current()
au lieu de Random()
.
Pour kotlinjs et d'autres cas d'utilisation qui ne permettent pas l'utilisation de java.util.Random
, cette réponse aidera.
Construire hors de @s1m0nw1 {[4] } excellente réponse j'ai fait les changements suivants.
- (0..n) implique inclusif dans Kotlin
- (0 jusqu'à n) implique exclusive dans Kotlin
- utiliser un objet singleton pour L'instance aléatoire (facultatif)
Code:
private object RandomRangeSingleton : Random()
fun ClosedRange<Int>.random() = RandomRangeSingleton.nextInt((endInclusive + 1) - start) + start
Cas De Test:
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())
}
)
}
Exemples aléatoires dans la plage [1, 10]
val random1 = (0..10).shuffled().last()
Ou en utilisant Java Random
val random2 = Random().nextInt(10) + 1
Si vous travaillez avec Kotlin JavaScript et n'ont pas accès à java.util.Random
, ce qui suit fonctionnera:
fun IntRange.random() = (Math.random() * ((endInclusive + 1) - start) + start).toInt()
Utilisé comme ceci:
// will return an `Int` between 0 and 10 (incl.)
(0..10).random()
Une autre façon d'implémenter la réponse de s1m0nw1 serait d'y accéder via une variable. Ce n'est pas plus efficace mais cela vous évite d'avoir à taper ().
var ClosedRange<Int>.random: Int
get() { return Random().nextInt((endInclusive + 1) - start) + start }
private set(value) {}
Et maintenant il peut être consulté en tant que tel
(1..10).random
En utilisant une fonction de niveau supérieur, vous pouvez obtenir exactement la même syntaxe d'appel que dans Ruby (comme vous le souhaitez):
fun rand(s: Int, e: Int) = Random().nextInt(e + 1 - s) + s
Utilisation:
rand(1, 3) // returns either 1, 2 or 3
D'abord, vous avez besoin D'un RNG. Dans Kotlin, vous devez actuellement utiliser les plates-formes spécifiques (il n'y a pas de Kotlin construit en un). Pour la JVM, c'est java.util.Random
. Vous devrez en créer une instance, puis appeler random.nextInt(n)
.
Il N'y a pas de méthode standard qui le fait mais vous pouvez facilement créer le vôtre en utilisant Math.random()
ou la classe java.util.Random
. Voici un exemple utilisant la méthode 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) })
}
Ceci est un exemple de sortie:
[9, 8, 1, 7, 5, 6, 9, 8, 1, 9]
[5, 8, 9, 7, 6, 6, 8, 6, 7, 9]
Si les nombres que vous voulez choisir ne sont pas consécutifs, vous pouvez définir votre propre fonction d'extension sur la liste:
fun List<*>.randomElement()
= if (this.isEmpty()) null else this[Random().nextInt(this.size)]
Utilisation:
val list = listOf(3, 1, 4, 5)
val number = list.randomElement()
Renvoie l'un des nombres qui sont dans la liste.
Kotlin standard lib ne fournit pas D'API de générateur de nombres aléatoires. Si vous n'êtes pas dans un projet multiplateforme, il est préférable d'utiliser l'api de plate-forme (toutes les autres réponses de la question parlent de cette solution).
Mais si vous êtes dans un contexte multiplateforme, la meilleure solution est d'implémenter random par vous-même dans Kotlin pur pour partager le même générateur de nombres aléatoires entre les plates-formes.{[8] }c'est plus simple pour dev et testing.
Pour répondre à ce problème dans mon projet personnel, j'implémente un générateur Congruentiel linéaire Kotlin pur . LCG est l'algorithme utilisé par java.util.Random
. Suivez ce lien si vous voulez l'utiliser :
https://gist.github.com/11e5ddb567786af0ed1ae4d7f57441d4
Mon but d'implémentation nextInt(range: IntRange)
pour vous ;).
Prenez soin de mon but, LCG est bon pour la plupart des cas d'utilisation (simulation, Jeux,etc...) mais ne convient pas à une utilisation cryptographique en raison de la prévisibilité de cette méthode.
Dans Kotlin 1.3 vous pouvez le faire comme
val number = Random.nextInt(limit)