web-dev-qa-db-fra.com

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).

Toute suggestion?

78
Yago Azedias

Ma suggestion serait une fonction extension sur IntRange pour créer des aléas comme celui-ci: (0..10).random()

TL; DR Kotlin> = 1,3, un aléatoire pour toutes les plateformes

À 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()

Kotlin <1.3

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 Chars aléatoire.

231
s1m0nw1

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
}
39
Magnus

À 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

26
mutexkid

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
10
mfulton26

Variation possible de mon autre réponse pour les caractères aléatoires

Pour obtenir des Chars 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.

Kotlin> = 1.3 support multiplateforme pour Random

À 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()
8
s1m0nw1

Construisant à partir de @ s1m0nw1 excellente réponse, j'ai apporté les modifications suivantes.

  1. (0..n) implique l'inclusion dans Kotlin
  2. (0 jusqu'à n) implique une exclusivité Kotlin
  3. Utiliser un objet singleton pour l'occurrence 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())
                }
        )
    }
6
Steven Spungin

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
5
Andrey

Kotlin> = 1.3, support multiplateforme pour Random

À partir de la version 1.3, la bibliothèque standard offrait un support multi-plateforme pour les aléas. Voir this answer.

Kotlin <1.3 sur JavaScript

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()
4
s1m0nw1

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
3
Quinn

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
2
Willi Mentzel

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.

1
Willi Mentzel

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).

1
Mibac

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]
1
Mahdi AlKhalaf

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.

1
Valentin Michalak

Dans Kotlin 1.3, vous pouvez le faire comme

val number = Random.nextInt(limit)
0
deviant

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

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.

0
ARGeo

Plus besoin d'utiliser des fonctions d'extension personnalisées. IntRange a maintenant une fonction d'extension random() prête à l'emploi.

val randomNumber = (0..10).random()
0
Willi Mentzel