Общий метод, который может возвращать случайное целое число между двумя параметрами, такими как ruby, с rand(0..n)
Создайте случайное целое число from
(включительно) и to
(исключительного)
import java.util.Random val random = Random() fun rand(from: Int, to: Int) : Int { return random.nextInt(to - from) + from }
Я рекомендую использовать следующую функцию расширения :
fun ClosedRange<Int>.random() = Random().nextInt(endInclusive - start) + start
используйте его вот так:
// will return an `Int` between 0 and 9 (incl.) (0..10).random()
Если вы работаете с JDK> = 1.7, используйте ThreadLocalRandom.current()
вместо Random()
.
Также см. Этот ответ для вариантов.
Вы можете создать функцию расширения, похожую на java.util.Random.nextInt(int)
но IntRange
которая принимает IntRange
вместо Int
для своей привязки:
fun Random.nextInt(range: IntRange): Int { return range.start + nextInt(range.last - range.start) }
Теперь вы можете использовать это с любым экземпляром Random
:
val random = Random() println(random.nextInt(5..9)) // prints 5, 6, 7, or 8
Если вы не хотите управлять своим собственным экземпляром Random
то вы можете определить метод удобства, используя, например, ThreadLocalRandom.current()
:
fun rand(range: IntRange): Int { return ThreadLocalRandom.current().nextInt(range) }
Теперь вы можете получить случайное целое число, как в Ruby, без необходимости сначала объявлять Random
экземпляр самостоятельно:
rand(5..9) // returns 5, 6, 7, or 8
Исходя из превосходного ответа @ s1m0nw1, я внес следующие изменения.
Код:
private object RandomRangeSingleton : Random() fun ClosedRange<Int>.random() = RandomRangeSingleton.nextInt((endInclusive + 1) - start) + start
Прецедент:
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()) } ) }
Во-первых, вам нужен RNG. В Котлине вам в настоящее время нужно использовать специфичные для платформы (в одном из них нет котлина). Для JVM это java.util.Random
. Вам нужно создать экземпляр, а затем вызвать random.nextInt(n)
.
Существует стандартный метод, который делает это, но вы можете легко создать свой собственный, используя либо Math.random()
либо класс java.util.Random
. Вот пример использования 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) }) }
Это примерный результат:
[9, 8, 1, 7, 5, 6, 9, 8, 1, 9] [5, 8, 9, 7, 6, 6, 8, 6, 7, 9]
Используя функцию верхнего уровня, вы можете добиться точно такого же синтаксиса вызова, как в Ruby (по вашему усмотрению):
fun rand(s: Int, e: Int) = Random().nextInt(e + 1 - s) + s
Применение:
rand(1, 3) // returns either 1, 2 or 3
Возможные варианты моего ответа выше
a) Если вы хотите 0..10.random()
также включить значение 10
, необходимо следующее изменение:
fun ClosedRange<Int>.random() = Random().nextInt(endInclusive + 1 - start) + start
б) Чтобы получить случайный Char
s, вы можете определить функцию следующим образом:
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()
Если вы работаете с JDK> = 1.7, используйте ThreadLocalRandom.current()
вместо Random()
.
Если числа, которые вы хотите выбрать, не являются последовательными, вы можете определить свою собственную функцию расширения в списке:
fun List<*>.randomElement() = if (this.isEmpty()) null else this[Random().nextInt(this.size)]
Применение:
val list = listOf(3, 1, 4, 5) val number = list.randomElement()
Возвращает одно из чисел, которые находятся в списке.
Стандартная библиотека Kotlin не предоставляет API генератора случайных чисел. Если вы не в мультиплатформенном проекте, лучше использовать платформу api (все остальные ответы на вопрос об этом решении) .
Но если вы находитесь в мультиплатформенном контексте, лучшим решением является реализация случайных действий в чистом kotlin для совместного использования одного и того же генератора случайных чисел между платформами. Это проще для разработчиков и тестирования.
Чтобы ответить на эту проблему в моем личном проекте, я реализую чистый линейный конгруэнтный генератор Котлина. LCG – это алгоритм, используемый java.util.Random
. Следуйте этой ссылке, если вы хотите ее использовать: https://gist.github.com/11e5ddb567786af0ed1ae4d7f57441d4
Моя цель реализации nextInt(range: IntRange)
для вас;).
Позаботьтесь о моей цели, LCG хорош для большинства случаев использования (симуляция, игры и т. Д.), Но не подходит для криптографического использования из-за предсказуемости этого метода.