Eine generische Methode, die eine zufällige Ganzzahl zwischen zwei Parametern zurückgeben kann, wie es Ruby tut rand(0..n)
.
Irgendein Vorschlag?
Eine generische Methode, die eine zufällige Ganzzahl zwischen zwei Parametern zurückgeben kann, wie es Ruby tut rand(0..n)
.
Irgendein Vorschlag?
Antworten:
Mein Vorschlag wäre eine Erweiterungsfunktion in IntRange , um solche Zufälle zu erstellen:(0..10).random()
Ab 1.3 verfügt Kotlin über einen eigenen plattformübergreifenden Zufallsgenerator. Es wird in diesem KEEP beschrieben . Die unten beschriebene Erweiterung ist jetzt Teil der Kotlin-Standardbibliothek. Verwenden Sie sie einfach folgendermaßen:
val rnds = (0..10).random()
Vor 1.3 verwenden wir auf der JVM Random
oder auch ThreadLocalRandom
wenn wir auf JDK> 1.6 sind.
fun IntRange.random() =
Random().nextInt((endInclusive + 1) - start) + start
So verwendet:
// will return an `Int` between 0 and 10 (incl.)
(0..10).random()
Wenn Sie möchten, dass die Funktion nur zurückgegeben wird 1, 2, ..., 9
( 10
nicht enthalten), verwenden Sie einen Bereich mit until
:
(0 until 10).random()
Wenn Sie mit JDK> 1.6 arbeiten, verwenden Sie ThreadLocalRandom.current()
anstelle von Random()
.
KotlinJs und andere Variationen
Informationen zu Kotlinjs und anderen Anwendungsfällen, deren Verwendung nicht zulässig ist java.util.Random
, finden Sie in dieser Alternative .
In dieser Antwort finden Sie auch Variationen meines Vorschlags. Es enthält auch eine Erweiterungsfunktion für zufällige Char
s.
Generieren Sie eine zufällige Ganzzahl zwischen from
(einschließlich) und to
(exklusiv)
import java.util.Random
val random = Random()
fun rand(from: Int, to: Int) : Int {
return random.nextInt(to - from) + from
}
Int
Zufälle erhalten möchten , können Sie stattdessen Random # int (Größe, von, bis) in Java-8 verwenden .
Ab Kotlin 1.2 können Sie schreiben:
(1..3).shuffled().last()
Seien Sie sich nur bewusst, dass es ein großes O (n) ist, aber für eine kleine Liste (insbesondere mit eindeutigen Werten) ist es in Ordnung: D.
Sie können eine Erweiterungsfunktion erstellen java.util.Random.nextInt(int)
, die IntRange
der Int
für ihre Bindung ähnlich ist, jedoch eine anstelle einer :
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üssen, können Sie eine praktische Methode definieren, indem Sie beispielsweise Folgendes verwenden ThreadLocalRandom.current()
:
fun rand(range: IntRange): Int {
return ThreadLocalRandom.current().nextInt(range)
}
Jetzt können Sie wie in Ruby eine zufällige Ganzzahl erhalten, ohne zuvor selbst eine Random
Instanz deklarieren zu müssen :
rand(5..9) // returns 5, 6, 7, or 8
Mögliche Variation zu meiner anderen Antwort für zufällige Zeichen
Um zufällige Char
s zu erhalten, können Sie eine Erweiterungsfunktion wie diese 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, deren Verwendung nicht zulässig ist java.util.Random
, hilft diese Antwort .
Ab 1.3 verfügt Kotlin über einen eigenen Multiplattform-Zufallsgenerator. Es wird 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 die folgenden Ä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())
}
)
}
Beispiele zufällig im Bereich [1, 10]
val random1 = (0..10).shuffled().last()
oder mit Java Random
val random2 = Random().nextInt(10) + 1
Ab 1.3 bietet die Standardbibliothek Unterstützung für mehrere Plattformen, siehe diese Antwort.
Wenn Sie mit Kotlin JavaScript arbeiten und keinen Zugriff darauf haben java.util.Random
, funktioniert Folgendes:
fun IntRange.random() = (Math.random() * ((endInclusive + 1) - start) + start).toInt()
So verwendet:
// will return an `Int` between 0 and 10 (incl.)
(0..10).random()
Eine andere Möglichkeit, die Antwort von s1m0nw1 zu implementieren, besteht darin, über eine Variable darauf zuzugreifen. Nicht, dass es effizienter wäre, aber es erspart Ihnen die Eingabe von ().
val ClosedRange<Int>.random: Int
get() = Random().nextInt((endInclusive + 1) - start) + start
Und jetzt kann als solches darauf zugegriffen werden
(1..10).random
Es gibt keine Standardmethode, die dies tut, aber Sie können ganz einfach Ihre eigene Methode entweder mit Math.random()
oder mit der Klasse erstellen java.util.Random
. 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]
Die Kotlin-Standardbibliothek bietet keine Zufallszahlengenerator-API. Wenn Sie nicht in einem Multiplattform-Projekt sind, ist es besser, die Plattform-API zu verwenden (alle anderen Antworten auf die Frage sprechen von dieser Lösung) .
Wenn Sie sich jedoch in einem Multiplattform-Kontext befinden, besteht die beste Lösung darin, Random selbst in reinem Kotlin zu implementieren, um denselben Zufallszahlengenerator zwischen Plattformen zu teilen. Es ist einfacher für Entwickler und Tests.
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
. 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 eignet sich für die meisten Anwendungsfälle (Simulation, Spiele usw.) , ist jedoch aufgrund der Vorhersagbarkeit dieser Methode nicht für die kryptografische Verwendung geeignet.
In Kotlin 1.3 können Sie es so machen
val number = Random.nextInt(limit)
Wenn die Nummern, aus denen Sie auswählen möchten, nicht fortlaufend sind, können Sie sie verwenden random()
.
Verwendung:
val list = listOf(3, 1, 4, 5)
val number = list.random()
Gibt eine der Nummern zurück, die in der Liste enthalten sind.
Sie müssen keine benutzerdefinierten Erweiterungsfunktionen mehr verwenden. IntRange verfügt jetzt über eine sofort einsatzbereiterandom()
Erweiterungsfunktion.
val randomNumber = (0..10).random()
Mit einer Funktion der obersten Ebene können Sie genau die gleiche Aufrufsyntax wie in Ruby erzielen (wie Sie möchten):
fun rand(s: Int, e: Int) = Random.nextInt(s, e + 1)
Verwendung:
rand(1, 3) // returns either 1, 2 or 3
Zunächst benötigen Sie ein RNG. In Kotlin müssen Sie derzeit die plattformspezifischen verwenden (es ist kein Kotlin in einem integriert). Für die JVM ist es java.util.Random
. Sie müssen eine Instanz davon erstellen und dann aufrufen random.nextInt(n)
.
Um eine zufällige Int-Zahl in Kotlin zu erhalten, verwenden Sie 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.
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) 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()
}
Round Float-Wert:
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
Vollständiger Quellcode. Kann steuern, ob Duplikate zulässig sind.
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("")
}
}
}
Wann immer es eine Situation gibt, in der Sie eine Schlüssel- oder Mac-Adresse generieren möchten, bei der es sich um eine hexadezimale Zahl mit Ziffern handelt, die auf der Benutzeranforderung basieren, und dies auch unter Verwendung von Android und Kotlin, hilft Ihnen mein unten stehender Code:
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()
}
super duper sein))
fun rnd_int(min: Int, max: Int): Int {
var max = max
max -= min
return (Math.random() * ++max).toInt() + min
}
java.util.Random
?