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)
.
Toute suggestion?
Ma suggestion serait une fonction extension sur IntRange pour créer des aléas comme celui-ci: (0..10).random()
À partir de la version 1.3, Kotlin est livré avec son propre générateur aléatoire multi-plateformes. Il est décrit dans ce KEEP . L'extension décrite ci-dessous est maintenant partie de la bibliothèque standard Kotlin }, utilisez-la simplement comme ceci:
val rnds = (0..10).random()
Avant la version 1.3, sur la machine virtuelle Java, nous utilisions Random
ou même ThreadLocalRandom
si nous utilisions JDK> 1.6.
fun IntRange.random() =
Random().nextInt((endInclusive + 1) - start) + start
Utilisé 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
non inclus), utilisez une plage construite avec until
:
(0 until 10).random()
Si vous travaillez avec JDK> 1.6, utilisez ThreadLocalRandom.current()
au lieu de Random()
.
KotlinJs et autres variations
Pour les kotlinjs et autres cas d'utilisation n'autorisant pas l'utilisation de Java.util.Random
, voir cette alternative .
Voir aussi réponse pour connaître les variantes de ma suggestion. Il inclut également une fonction d’extension pour Char
s aléatoire.
Générer un entier aléatoire 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 gros O (n), mais pour une petite liste (en particulier de valeurs uniques) ça va: D
Vous pouvez créer une fonction extension similaire à Java.util.Random.nextInt(int)
, mais qui prend une IntRange
au lieu d'une Int
pour sa limite:
fun Random.nextInt(range: IntRange): Int {
return range.start + nextInt(range.last - range.start)
}
Vous pouvez maintenant l'utiliser avec n'importe quelle instance Random
:
val random = Random()
println(random.nextInt(5..9)) // prints 5, 6, 7, or 8
Si vous ne souhaitez pas gérer votre propre instance Random
, vous pouvez définir une méthode pratique en utilisant, par exemple, ThreadLocalRandom.current()
:
fun Rand(range: IntRange): Int {
return ThreadLocalRandom.current().nextInt(range)
}
Maintenant, vous pouvez obtenir un entier aléatoire comme vous le feriez avec Ruby sans avoir à déclarer 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
Pour obtenir des Char
s aléatoires, vous pouvez définir une fonction d'extension comme celle-ci
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, utilisez ThreadLocalRandom.current()
au lieu de Random()
.
Pour kotlinjs et autres cas d’utilisation qui ne permettent pas l’utilisation de Java.util.Random
, cette réponse aidera.
À partir de 1.3, Kotlin est livré avec son propre générateur Random multiplateforme. Il est décrit dans ce KEEP . Vous pouvez maintenant utiliser directement l'extension dans la bibliothèque standard Kotlin sans la définir:
('a'..'b').random()
Construisant à partir de @ s1m0nw1 excellente réponse, j'ai apporté les modifications suivantes.
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 l'intervalle [1, 10]
val random1 = (0..10).shuffled().last()
ou en utilisant Java Random
val random2 = Random().nextInt(10) + 1
À partir de la version 1.3, la bibliothèque standard offrait un support multi-plateforme pour les aléas. Voir this answer.
Si vous travaillez avec Kotlin JavaScript et n’avez 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 de mettre en œuvre la réponse de s1m0nw1 serait d'y accéder via une variable. Ce n’est pas plus efficace, mais cela vous évite de devoir 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 (à votre guise):
fun Rand(s: Int, e: Int) = Random.nextInt(s, e + 1)
Usage:
Rand(1, 3) // returns either 1, 2 or 3
Si les numéros que vous voulez choisir ne sont pas consécutifs, vous pouvez utiliser random()
.
Usage:
val list = listOf(3, 1, 4, 5)
val number = list.random()
Renvoie l'un des nombres figurant dans la liste.
Tout d'abord, vous avez besoin d'un RNG. Dans Kotlin, vous devez actuellement utiliser les plateformes spécifiques (il n’ya pas de Kotlin intégré). Pour la machine virtuelle, c'est Java.util.Random
. Vous devrez en créer une instance, puis appeler random.nextInt(n)
.
Aucune méthode standard ne permet cela, mais vous pouvez facilement créer la 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]
La bibliothèque standard Kotlin ne fournit pas l'API Random Number Generator. Si vous n'êtes pas dans un projet multiplateforme, il vaut mieux utiliser la plateforme api (toutes les autres réponses de la question parlent de cette solution)).
Mais si vous êtes dans un contexte multiplateforme, la meilleure solution consiste à implémenter de manière aléatoire vous-même en kotlin pur pour partager le même générateur de nombres aléatoires entre plates-formes. C'est plus simple pour les développeurs et les tests.
Pour répondre à ce problème dans mon projet personnel, j’implémente un générateur Kotlin Linear Congruential pur . LCG est l'algorithme utilisé par Java.util.Random
. Suivez ce lien si vous souhaitez l’utiliser: https://Gist.github.com/11e5ddb567786af0ed1ae4d7f57441d4
Mon objectif de mise en œuvre nextInt(range: IntRange)
pour vous;).
Faites attention à mon objectif, LCG est bon pour la plupart des cas d'utilisation (simulation, jeux, etc ...) mais n'est pas adapté à 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)
Vous pouvez créer une fonction d'extension:
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()
}
Valeur du flotteur rond:
fun Float.round(decimals: Int = DIGITS): Float {
var multiplier = 1.0f
repeat(decimals) { multiplier *= 10 }
return round(this * multiplier) / multiplier
}
Méthode d'utilisation:
(0.0f .. 1.0f).step(.1f).forEach { System.out.println("value: $it") }
Sortie:
valeur: 0,0 valeur: 0,1 valeur: 0,2 valeur: 0,3 valeur: 0,4 valeur: 0,5 valeur: 0,6 valeur: 0,7 valeur: 0,8 valeur: 0,9 valeur: 1,0
Pour obtenir un numéro Int aléatoire dans Kotlin, utilisez la méthode suivante :
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
J'espère que cela t'aides.