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?
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?
Réponses:
Ma suggestion serait une fonction d' extension sur IntRange pour créer des aléas comme ceci:(0..10).random()
Depuis la version 1.3, Kotlin est livré avec son propre générateur aléatoire multi-plateforme. Il est décrit dans ce KEEP . L'extension décrite ci-dessous fait maintenant partie de la bibliothèque standard Kotlin , utilisez-la simplement comme ceci:
val rnds = (0..10).random()
Avant 1.3, sur la JVM on utilise Random
ou même ThreadLocalRandom
si on est sur 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 souhaitez que la fonction renvoie uniquement 1, 2, ..., 9
( 10
non incluse), utilisez une plage construite avec until
:
(0 until 10).random()
Si vous travaillez avec JDK> 1.6, utilisez à la ThreadLocalRandom.current()
place de Random()
.
KotlinJs et autres variantes
Pour les kotlinjs et autres cas d'utilisation qui ne permettent pas l'utilisation de java.util.Random
, consultez cette alternative .
Voir également cette réponse pour les variations de ma suggestion. Il comprend également une fonction d'extension pour les Char
s aléatoires .
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
}
Int
s aléatoires à distance , vous pouvez utiliser Random # int (size, from, to) à la place dans java-8 .
Depuis kotlin 1.2, vous pouvez écrire:
(1..3).shuffled().last()
Sachez simplement que c'est un gros O (n), mais pour une petite liste (en particulier des valeurs uniques), tout va bien: D
Vous pouvez créer une fonction d'extension similaire à java.util.Random.nextInt(int)
mais qui prend un IntRange
au lieu d'un Int
pour sa borne:
fun Random.nextInt(range: IntRange): Int {
return range.start + nextInt(range.last - range.start)
}
Vous pouvez maintenant l'utiliser avec n'importe quelle Random
instance:
val random = Random()
println(random.nextInt(5..9)) // prints 5, 6, 7, or 8
Si vous ne souhaitez pas avoir à gérer votre propre Random
instance, vous pouvez définir une méthode pratique en utilisant, par exemple ThreadLocalRandom.current()
,:
fun rand(range: IntRange): Int {
return ThreadLocalRandom.current().nextInt(range)
}
Vous pouvez maintenant obtenir un entier aléatoire comme vous le feriez dans Ruby sans avoir à déclarer d'abord une Random
instance vous-même:
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
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 à la ThreadLocalRandom.current()
place de Random()
.
Pour les kotlinjs et autres cas d'utilisation qui ne permettent pas l'utilisation de java.util.Random
, cette réponse vous aidera.
Depuis la 1.3, Kotlin est livré avec son propre générateur aléatoire multiplateforme. Il est décrit dans ce KEEP . Vous pouvez désormais utiliser directement l'extension dans le cadre de la bibliothèque standard Kotlin sans la définir:
('a'..'b').random()
En s'appuyant sur l' excellente réponse @ s1m0nw1, 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 la plage [1, 10]
val random1 = (0..10).shuffled().last()
ou en utilisant Java Random
val random2 = Random().nextInt(10) + 1
Depuis la version 1.3, la bibliothèque standard fournissait un support multi-plateforme pour les aléas, voir cette réponse.
Si vous travaillez avec Kotlin JavaScript et que vous 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 d'implémenter la réponse de s1m0nw1 serait d'y accéder via une variable. Non pas que ce soit plus efficace mais cela vous évite d'avoir à taper ().
val ClosedRange<Int>.random: Int
get() = Random().nextInt((endInclusive + 1) - start) + start
Et maintenant, il est accessible en tant que tel
(1..10).random
Il n'y a pas de méthode standard pour cela, mais vous pouvez facilement créer la vôtre en utilisant l'un Math.random()
ou l' autre ou la classe java.util.Random
. Voici un exemple utilisant la Math.random()
méthode:
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 de Kotlin ne fournit pas d'API Random Number Generator. Si vous n'êtes pas dans un projet multiplateforme, il vaut mieux utiliser l'api de la plateforme (toutes les autres réponses à la question parlent de cette solution) .
Mais si vous êtes dans un contexte multiplateforme, la meilleure solution est d'implémenter l'aléatoire par vous-même en kotlin pur pour partager le même générateur de nombres aléatoires entre les plateformes. C'est plus simple pour le développement et les tests.
Pour répondre à ce problème dans mon projet personnel, j'implémente un pur générateur de congruence linéaire Kotlin . 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 ne convient pas à une utilisation cryptographique en raison de la prévisibilité de cette méthode.
Si les numéros que vous souhaitez 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.
Plus besoin d'utiliser des fonctions d'extension personnalisées. IntRange a maintenant une random()
fonction d'extension prête à l'emploi .
val randomNumber = (0..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(s, e + 1)
Usage:
rand(1, 3) // returns either 1, 2 or 3
Tout 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 intégré). Pour la JVM, c'est java.util.Random
. Vous devrez en créer une instance, puis appeler random.nextInt(n)
.
Pour obtenir un nombre 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.
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 flottante ronde:
fun Float.round(decimals: Int = DIGITS): Float {
var multiplier = 1.0f
repeat(decimals) { multiplier *= 10 }
return round(this * multiplier) / multiplier
}
Utilisation de la méthode:
(0.0f .. 1.0f).step(.1f).forEach { System.out.println("value: $it") }
Production:
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
Code source complet. Peut contrôler si les doublons sont autorisés.
import kotlin.math.min
abstract class Random {
companion object {
fun string(length: Int, isUnique: Boolean = false): String {
if (0 == length) return ""
val alphabet: List<Char> = ('a'..'z') + ('A'..'Z') + ('0'..'9') // Add your set here.
if (isUnique) {
val limit = min(length, alphabet.count())
val set = mutableSetOf<Char>()
do { set.add(alphabet.random()) } while (set.count() != limit)
return set.joinToString("")
}
return List(length) { alphabet.random() }.joinToString("")
}
fun alphabet(length: Int, isUnique: Boolean = false): String {
if (0 == length) return ""
val alphabet = ('A'..'Z')
if (isUnique) {
val limit = min(length, alphabet.count())
val set = mutableSetOf<Char>()
do { set.add(alphabet.random()) } while (set.count() != limit)
return set.joinToString("")
}
return List(length) { alphabet.random() }.joinToString("")
}
}
}
Chaque fois qu'il y a une situation où vous souhaitez générer une clé ou une adresse mac qui est un nombre hexadécimal ayant des chiffres basés sur la demande de l'utilisateur, et cela aussi en utilisant Android et Kotlin, alors mon code ci-dessous vous aide:
private fun getRandomHexString(random: SecureRandom, numOfCharsToBePresentInTheHexString: Int): String {
val sb = StringBuilder()
while (sb.length < numOfCharsToBePresentInTheHexString) {
val randomNumber = random.nextInt()
val number = String.format("%08X", randomNumber)
sb.append(number)
}
return sb.toString()
}
être super duper))
fun rnd_int(min: Int, max: Int): Int {
var max = max
max -= min
return (Math.random() * ++max).toInt() + min
}
java.util.Random
?