Eine generische Methode, die eine zufällige Ganzzahl zwischen zwei Parametern zurückgeben kann, wie dies Ruby mit Rand(0..n)
tut.
Irgendein Vorschlag?
Mein Vorschlag wäre eine Erweiterung Funktion auf IntRange , um Random wie folgt zu erstellen: (0..10).random()
Kotlin verfügt ab 1.3 über einen eigenen Multi-Plattform-Zufallsgenerator. Es ist in diesem KEEP beschrieben. Die unten beschriebene Erweiterung ist jetzt Teil der Kotlin-Standardbibliothek , verwenden Sie sie einfach wie folgt:
val rnds = (0..10).random()
Vor 1.3 verwenden wir in der JVM Random
oder sogar ThreadLocalRandom
, wenn wir uns auf JDK> 1.6 befinden.
fun IntRange.random() =
Random().nextInt((endInclusive + 1) - start) + start
So benutzt:
// will return an `Int` between 0 and 10 (incl.)
(0..10).random()
Wenn die Funktion nur 1, 2, ..., 9
(10
nicht enthalten) zurückgeben soll, verwenden Sie einen mit until
erstellten Bereich: _:
(0 until 10).random()
Wenn Sie mit JDK> 1.6 arbeiten, verwenden Sie ThreadLocalRandom.current()
anstelle von Random()
.
KotlinJs und andere Variationen
Für kotlinjs und andere Anwendungsfälle, die die Verwendung von Java.util.Random
nicht zulassen, siehe diese Alternative .
Siehe auch dieses answer für Variationen meines Vorschlags. Es enthält auch eine Erweiterungsfunktion für zufällige Char
s.
Generiere eine zufällige Ganzzahl zwischen from
(inklusive) und to
(exklusiv)
import Java.util.Random
val random = Random()
fun Rand(from: Int, to: Int) : Int {
return random.nextInt(to - from) + from
}
Ab kotlin 1.2 können Sie schreiben:
(1..3).shuffled().last()
Seien Sie sich bewusst, dass es ein großes O (n) ist, aber für eine kleine Liste (insbesondere von eindeutigen Werten) ist es in Ordnung: D
Sie können eine extension-Funktion erstellen, die Java.util.Random.nextInt(int)
ähnelt, aber eine, die IntRange
anstelle einer Int
für ihre Begrenzung verwendet:
fun Random.nextInt(range: IntRange): Int {
return range.start + nextInt(range.last - range.start)
}
Sie können dies jetzt mit jeder Random
Instanz verwenden:
val random = Random()
println(random.nextInt(5..9)) // prints 5, 6, 7, or 8
Wenn Sie keine eigene Random
-Instanz verwalten möchten, können Sie eine Komfortmethode definieren, z. B. ThreadLocalRandom.current()
:
fun Rand(range: IntRange): Int {
return ThreadLocalRandom.current().nextInt(range)
}
Jetzt können Sie eine zufällige Ganzzahl wie in Ruby erhalten, ohne vorher eine Random
-Instanz deklarieren zu müssen:
Rand(5..9) // returns 5, 6, 7, or 8
Mögliche Variation zu meinem andere Antwort für zufällige Zeichen
Um zufällige Char
s zu erhalten, können Sie eine Erweiterungsfunktion wie folgt definieren
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()
Wenn Sie mit JDK> 1.6 arbeiten, verwenden Sie ThreadLocalRandom.current()
anstelle von Random()
.
Für kotlinjs und andere Anwendungsfälle, die die Verwendung von Java.util.Random
nicht zulassen, hilft diese Antwort .
Kotlin verfügt ab 1.3 über einen eigenen Multiplattform-Zufallsgenerator. Es ist in diesem KEEP beschrieben. Sie können die Erweiterung jetzt direkt als Teil der Kotlin-Standardbibliothek verwenden, ohne sie zu definieren:
('a'..'b').random()
Aufbauend auf @ s1m0nw1 ausgezeichnete Antwort Ich habe folgende Änderungen vorgenommen.
Code:
private object RandomRangeSingleton : Random()
fun ClosedRange<Int>.random() = RandomRangeSingleton.nextInt((endInclusive + 1) - start) + start
Testfall:
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())
}
)
}
Zufällige Beispiele im Bereich [1, 10]
val random1 = (0..10).shuffled().last()
oder unter Verwendung von Java Random
val random2 = Random().nextInt(10) + 1
Seit 1.3 bietet die Standardbibliothek Unterstützung für mehrere Plattformen für Randoms, siehe this answer.
Wenn Sie mit Kotlin JavaScript arbeiten und keinen Zugriff auf Java.util.Random
haben, wird Folgendes funktionieren:
fun IntRange.random() = (Math.random() * ((endInclusive + 1) - start) + start).toInt()
So benutzt:
// will return an `Int` between 0 and 10 (incl.)
(0..10).random()
Eine andere Möglichkeit, die Antwort von s1m0nw1 zu implementieren, wäre der Zugriff über eine Variable. Das ist zwar nicht effizienter, aber es erspart Ihnen das Tippen von ().
var ClosedRange<Int>.random: Int
get() { return Random().nextInt((endInclusive + 1) - start) + start }
private set(value) {}
Und jetzt ist es als solches zugänglich
(1..10).random
Mit einer Top-Level-Funktion können Sie genau dieselbe Aufrufsyntax wie in Ruby erzielen (wie Sie möchten):
fun Rand(s: Int, e: Int) = Random.nextInt(s, e + 1)
Verwendungszweck:
Rand(1, 3) // returns either 1, 2 or 3
Wenn die Nummern, aus denen Sie auswählen möchten, nicht fortlaufend sind, können Sie random()
verwenden.
Verwendungszweck:
val list = listOf(3, 1, 4, 5)
val number = list.random()
Gibt eine der Zahlen aus der Liste zurück.
Zunächst benötigen Sie einen RNG. In Kotlin müssen Sie derzeit die Plattform-spezifischen verwenden (es ist kein Kotlin eingebaut). Für die JVM ist es Java.util.Random
. Sie müssen eine Instanz davon erstellen und dann random.nextInt(n)
aufrufen.
Es gibt keine Standardmethode, die dies tut, aber Sie können Ihre eigene Methode mit Math.random()
oder der Klasse Java.util.Random
erstellen. Hier ist ein Beispiel mit der Math.random()
Methode:
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) })
}
Dies ist eine Beispielausgabe:
[9, 8, 1, 7, 5, 6, 9, 8, 1, 9]
[5, 8, 9, 7, 6, 6, 8, 6, 7, 9]
Kotlin standard lib bietet keine Zufallszahlengenerator-API. Wenn Sie sich nicht in einem Multiplattform-Projekt befinden, verwenden Sie die Plattform api (alle anderen Antworten der Frage beziehen sich auf diese Lösung).
Wenn Sie sich jedoch in einem Kontext mit mehreren Plattformen befinden, ist die beste Lösung die Implementierung der Zufallszahlen in reinen Kotlin, um den gleichen Zufallszahlengenerator zwischen den Plattformen zu teilen. Für Entwickler und Tests ist es einfacher.
Um dieses Problem in meinem persönlichen Projekt zu beantworten, implementiere ich einen reinen Kotlin Linear Congruential Generator . LCG ist der von Java.util.Random
verwendete Algorithmus. Folgen Sie diesem Link, wenn Sie ihn verwenden möchten: https://Gist.github.com/11e5ddb567786af0ed1ae4d7f57441d4
Mein Implementierungszweck nextInt(range: IntRange)
für Sie;).
Achten Sie auf meinen Zweck. LCG ist für die meisten Anwendungsfälle geeignet. (Simulation, Spiele usw.), ist jedoch aufgrund der Vorhersagbarkeit dieser Methode nicht für die kryptografische Verwendung geeignet.
In Kotlin 1.3 kann man das gerne machen
val number = Random.nextInt(limit)
Sie können eine Erweiterungsfunktion erstellen:
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) [email protected] null
val next = previous + step.round()
if (next > endInclusive) null else next.round()
}.asIterable()
}
return generateSequence(start) { previous ->
if (previous == Float.NEGATIVE_INFINITY) [email protected] null
val next = previous - step.round()
if (next < endInclusive) null else next.round()
}.asIterable()
}
Runder Gleitkommawert:
fun Float.round(decimals: Int = DIGITS): Float {
var multiplier = 1.0f
repeat(decimals) { multiplier *= 10 }
return round(this * multiplier) / multiplier
}
Verwendung der Methode:
(0.0f .. 1.0f).step(.1f).forEach { System.out.println("value: $it") }
Ausgabe:
wert: 0,0 Wert: 0,1 Wert: 0,2 Wert: 0,3 Wert: 0,4 Wert: 0,5 Wert: 0,6 Wert: 0,7 Wert: 0,8 Wert: 0,9 Wert: 1,0
Um eine zufällige Int-Zahl in Kotlin zu erhalten, verwende die folgende Methode :
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
Hoffe das hilft.