Как я могу получить случайное число в Котлин?



универсальный метод, который может возвращать случайное целое число между 2 параметрами, как ruby делает с rand(0..n).



есть предложения?

1707   15  

15 ответов:

Котлин

я предлагаю использовать следующие расширение

сгенерировать случайное целое число между from(включительно) и to(эксклюзив)

import java.util.Random

val random = Random()

fun rand(from: Int, to: Int) : Int {
    return random.nextInt(to - from) + from
}

начиная с 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,ответ поможет.

строительство @s1m0nw1 отличный ответ, я сделал следующие изменения.

  1. (0..n) подразумевает включительно в Котлин
  2. (0 до n) подразумевает эксклюзив в Котлине
  3. используйте одноэлементный объект для случайного экземпляра (необязательно)

код:

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

Если вы работаете с Котлин JavaScript и не имеют доступа к 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 - это доступ к нему через переменную. Не то чтобы это было более эффективно, но это избавляет вас от необходимости вводить ().

var ClosedRange<Int>.random: Int
    get() { return Random().nextInt((endInclusive + 1) - start) +  start }
    private set(value) {}

и теперь он может быть доступен как таковой

(1..10).random

используя функцию верхнего уровня, вы можете добиться точно такого же синтаксиса вызова, как и в Ruby (как вы хотите):

fun rand(s: Int, e: Int) = Random().nextInt(e + 1 - s) + s

использование:

rand(1, 3) // returns either 1, 2 or 3

во-первых, вам нужен ГСЧ. В Kotlin в настоящее время вам нужно использовать платформы конкретных из них (нет Котлин построен в одном). Для 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]

Если числа, которые вы хотите выбрать, не являются последовательными, вы можете определить свою собственную функцию расширения в списке:

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 standard lib не предоставляет API генератора случайных чисел. Если вы не находитесь в мультиплатформенном проекте, лучше использовать API платформы (все остальные ответы на вопрос говорят об этом решении).

но если вы находитесь в мультиплатформенном контексте, лучшим решением является реализация random самостоятельно в чистом Котлине для совместного использования одного и того же генератора случайных чисел между платформами. это более просто для dev и тестирование.

чтобы ответить на эту проблему в моем личном проекте, я реализую чистый Котлин Линейный Конгруэнтный Генератор. LCG-это алгоритм, используемый java.util.Random. Перейдите по этой ссылке, Если вы хотите использовать его : https://gist.github.com/11e5ddb567786af0ed1ae4d7f57441d4

моя цель реализации nextInt(range: IntRange) для вас ;).

позаботьтесь о моей цели, LCG хорош для большинства случаев использования (моделирование, игры и т. д...) но не подходит для криптографического использования из-за предсказуемости этого метода.

в Котлин 1.3 вы можете сделать это как

val number = Random.nextInt(limit)

Comments

    Ничего не найдено.