Узагальнений метод, який може повернути випадкове ціле число між двома параметрами, як і рубін rand(0..n).
Будь-яка пропозиція?
Узагальнений метод, який може повернути випадкове ціле число між двома параметрами, як і рубін rand(0..n).
Будь-яка пропозиція?
Відповіді:
Моєю пропозицією буде функція розширення на IntRange для створення таких рандов :(0..10).random()
Станом на 1.3, Kotlin має власний багатоплатформенний генератор Random. Це описано в цьому KEEP . Описане нижче розширення тепер є частиною стандартної бібліотеки Котліна , просто використовуйте його так:
val rnds = (0..10).random()
До 1.3 в JVM ми використовуємо Randomабо навіть ThreadLocalRandomякщо ми на JDK> 1.6.
fun IntRange.random() =
Random().nextInt((endInclusive + 1) - start) + start
Використовується так:
// will return an `Int` between 0 and 10 (incl.)
(0..10).random()
Якщо ви хотіли, щоб функція поверталася 1, 2, ..., 9( 10не включається), використовуйте діапазон, побудований з until:
(0 until 10).random()
Якщо ви працюєте з JDK> 1.6, використовуйте ThreadLocalRandom.current()замість Random().
KotlinJs та інші варіанти
Для котлінгів та інших випадків використання, які не дозволяють використовувати java.util.Random, див. Цю альтернативу .
Також дивіться цю відповідь щодо варіантів моєї пропозиції. Він також включає функцію розширення для випадкових Chars.
Створити випадкове ціле число між from(включно) та to(виключно)
import java.util.Random
val random = Random()
fun rand(from: Int, to: Int) : Int {
return random.nextInt(to - from) + from
}
Ints, ви можете використовувати Random # int (розмір, від, до) замість java-8 .
Станом на kotlin 1.2, ви можете написати:
(1..3).shuffled().last()
Просто пам’ятайте, що це великий O (n), але для невеликого списку (особливо унікальних значень) це добре: D
Ви можете створити функцію розширення, схожу на функцію розширення,java.util.Random.nextInt(int) але 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
Можливий варіант моєї іншої відповіді для випадкових символів
Для отримання випадкових Chars, ви можете визначити функцію розширення, як це
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.6, використовуйте ThreadLocalRandom.current() замість Random().
Для kotlinjs та інших випадків використання, які не дозволяють використовувати java.util.Random, ця відповідь допоможе.
Станом на 1.3, Котлін має власний багатоплатформенний генератор випадкових випадків. Це описано в цьому KEEP . Тепер ви можете безпосередньо використовувати розширення як частину стандартної бібліотеки Котліна, не визначаючи його:
('a'..'b').random()
Будівництво геть @ 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())
}
)
}
Приклади випадкових у діапазоні [1, 10]
val random1 = (0..10).shuffled().last()
або використання Java Random
val random2 = Random().nextInt(10) + 1
Станом на 1.3, стандартна бібліотека надала багатоплатформенну підтримку рандомів, див. Цю відповідь.
Якщо ви працюєте з JavaScript Kotlin і не маєте доступу до них java.util.Random, буде працювати наступне:
fun IntRange.random() = (Math.random() * ((endInclusive + 1) - start) + start).toInt()
Використовується так:
// will return an `Int` between 0 and 10 (incl.)
(0..10).random()
Іншим способом реалізації відповіді s1m0nw1 було б доступ до неї через змінну. Це не більш ефективно, але це позбавляє вас від необхідності вводити ().
val ClosedRange<Int>.random: Int
get() = Random().nextInt((endInclusive + 1) - start) + start
І тепер до нього можна отримати доступ як такий
(1..10).random
У Kotlin 1.3 ви можете робити так, як
val number = Random.nextInt(limit)
Не існує стандартного методу, який це робить, але ви можете легко створити свій власний, використовуючи 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]
Стандартна lib Kotlin не забезпечує API генератора випадкових чисел. Якщо ви не є багатоплатформою, краще скористатися платформою api (всі інші відповіді на питання говорять про це рішення) .
Але якщо ви перебуваєте в мультиплатформенному контексті, найкращим рішенням є реалізація випадкових власних зусиль у чистому котліні для спільного використання одного і того ж генератора випадкових чисел між платформами. Це простіше для розробників і тестування.
Щоб відповісти на цю проблему в особистому проекті, я реалізую чистий лінійний конгрурентний генератор Котліна . LCG - алгоритм, яким користуються java.util.Random. Перейдіть за цим посиланням, якщо бажаєте ним скористатися:
https://gist.github.com/11e5ddb567786af0ed1ae4d7f57441d4
Моя мета nextInt(range: IntRange)для вас;).
Подбайте про моє призначення, LCG хороший для більшості випадків використання (моделювання, ігри тощо), але не підходить для використання криптографічно через передбачуваність цього методу.
Якщо числа, які ви хочете вибрати, не є послідовними, ви можете використовувати random().
Використання:
val list = listOf(3, 1, 4, 5)
val number = list.random()
Повертає одне з номерів, що знаходяться у списку.
Використовуючи функцію верхнього рівня, ви можете домогтися того самого синтаксису виклику, що і в Ruby (як хочете):
fun rand(s: Int, e: Int) = Random.nextInt(s, e + 1)
Використання:
rand(1, 3) // returns either 1, 2 or 3
По-перше, вам потрібен RNG. На даний момент у Котліні вам потрібно використовувати конкретні платформи (у них немає вбудованого Kotlin). Для віртуальної машини Java це java.util.Random. Вам потрібно буде створити його примірник, а потім зателефонувати random.nextInt(n).
Для отримання випадкового Int числа в Котліні використовуйте наступний метод :
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
Сподіваюся, це допомагає.
Ви можете створити функцію розширення:
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()
}
Значення круглого поплавця:
fun Float.round(decimals: Int = DIGITS): Float {
var multiplier = 1.0f
repeat(decimals) { multiplier *= 10 }
return round(this * multiplier) / multiplier
}
Використання методу:
(0.0f .. 1.0f).step(.1f).forEach { System.out.println("value: $it") }
Вихід:
значення: 0,0 значення: 0,1 значення: 0,2 значення: 0,3 значення: 0,4 значення: 0,5 значення: 0,6 значення: 0,7 значення: 0,8 значення: 0,9 значення: 1,0
Повний вихідний код. Може контролювати, чи дозволені копії.
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("")
}
}
}
Щоразу, коли виникає ситуація, коли ви хочете генерувати ключ або mac-адресу, яка є шістнадцятковим числом, має цифри на основі попиту користувача, а також, використовуючи android та kotlin, то мій нижче код допоможе вам:
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()
}
бути супер пупер))
fun rnd_int(min: Int, max: Int): Int {
var max = max
max -= min
return (Math.random() * ++max).toInt() + min
}
java.util.Random?