web-dev-qa-db-ja.com

Kotlinで乱数を入手するにはどうすればいいですか?

Rubyのように2つのパラメータの間のランダムな整数を返すことができる一般的な方法はRand(0..n)で行います。

なにか提案を?

94
Yago Azedias

私の提案は、このようなランダムを作成するための IntRange 上の extension 関数でしょう:(0..10).random()

TL; DR Kotlin> = 1.3、1すべてのプラットフォームにランダム

1.3以降、Kotlinは独自のマルチプラットフォームのランダムジェネレータを搭載しています。これは KEEP で説明されています。以下で説明する拡張子は Kotlin標準ライブラリの一部 です。単に次のように使用してください。

val rnds = (0..10).random()

コトリン<1.3

1.3より前のバージョンでは、JVM上でRandom、あるいはJDK> 1.6を使用している場合はThreadLocalRandomを使用していました。

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と他のバリエーション

KotlinjsやJava.util.Randomの使用を許可しないその他の使用例については、 この代替 を参照してください。

また、私の提案のバリエーションについては answer を見てください。ランダムなCharsのための拡張関数も含まれています。

258
s1m0nw1

from(これを含む)とto(exclusive)の間のランダムな整数を生成する

import Java.util.Random

val random = Random()

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

Kotlin 1.2では、次のように書くことができます。

(1..3).shuffled().last()

それが大きいO(n)に注意してください、しかし小さいリスト(特にユニークな値の)のためにそれは大丈夫です:D

27
mutexkid

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)
}

最初にRandomインスタンスを自分で宣言しなくても、Rubyのようにランダムな整数を得ることができます。

Rand(5..9) // returns 5, 6, 7, or 8
10
mfulton26

私の 他の答え のランダムな文字のバリエーション

ランダムな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() を使用してください。

Java.util.Randomの使用を許可しないkotlinjsやその他のユースケースでは、 この回答 が役に立ちます。

Kotlin> = 1.3のマルチプラットフォーム対応のRandom

1.3の時点で、Kotlinは独自のマルチプラットフォームのランダムジェネレータを搭載しています。これは KEEP で説明されています。定義しなくても、Kotlin標準ライブラリの一部として直接使用することができます。

('a'..'b').random()
8
s1m0nw1

@ s1m0nw1からの構築 すばらしい答え私は以下の変更を行いました。

  1. (0..n)はKotlinを含むことを意味します
  2. (0からn)はKotlinで排他的であることを意味します
  3. Randomインスタンスにシングルトンオブジェクトを使う(オプション)

コード:

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())
                }
        )
    }
7
Steven Spungin

[1、10]の範囲でランダムな例

val random1 = (0..10).shuffled().last()

またはJava Randomの利用

val random2 = Random().nextInt(10) + 1
5
Andrey

Kotlin> = 1.3、Randomのマルチプラットフォームサポート

1.3の時点で、標準ライブラリはrandomsをマルチプラットフォームでサポートしていました。 this answerを参照してください。

JavaScriptでKotlin <1.3

Kotlin 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()
4
s1m0nw1

S1m0nw1の答えを実装するもう1つの方法は、変数を介してそれにアクセスすることです。それよりも効率的ではありませんが、type()を使わなくて済みます。

val ClosedRange<Int>.random: Int
    get() = Random().nextInt((endInclusive + 1) - start) +  start 

そして今、それはそのようにアクセスすることができます

(1..10).random
4
Quinn

トップレベルの関数を使うと、Rubyとまったく同じ呼び出し構文を実現できます(あなたが望むとおり)。

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

使用法:

Rand(1, 3) // returns either 1, 2 or 3
2
Willi Mentzel

選択したい番号が連続していない場合は、 random() を使用できます。

使用法:

val list = listOf(3, 1, 4, 5)
val number = list.random()

リストにある番号の1つを返します。

2
Willi Mentzel

これを行う標準的な方法はありませんが、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]
2
Mahdi AlKhalaf

Kotlin 1.3では、次のようにできます。

val number = Random.nextInt(limit)
1
deviant

まず、RNGが必要です。 Kotlinでは、現在プラットフォーム固有のものを使用する必要があります(Kotlinが組み込まれているわけではありません)。 JVMの場合は Java.util.Random です。そのインスタンスを作成してからrandom.nextInt(n)を呼び出す必要があります。

1
Mibac

Kotlin標準ライブラリは、乱数ジェネレーターAPIを提供しません。マルチプラットフォームプロジェクトに参加していない場合は、プラットフォームAPIを使用することをお勧めします(質問の他のすべての回答は、このソリューションについて話します)

しかし、あなたがマルチプラットフォームのコンテキストにいる場合、最良の解決策は、プラットフォーム間で同じ乱数ジェネレータを共有するために純粋なkotlinでランダムに実装することです。開発およびテストがより簡単になりました。

私の個人的なプロジェクトでこの問題に答えるために、純粋なKotlin Linear Congruential Generator を実装します。 LCGは、Java.util.Randomで使用されるアルゴリズムです。使用する場合は、このリンクに従ってください: https://Gist.github.com/11e5ddb567786af0ed1ae4d7f57441d4

あなたのための私の実装目的nextInt(range: IntRange);)。

私の目的に注意してください、LCGはほとんどのユースケース(シミュレーション、ゲームなど)には適していますが、この予測可能性のために暗号化の使用には適していません方法。

1

カスタム拡張機能を使用する必要はもうありません。 IntRangerandom() 拡張関数が追加されました。

val randomNumber = (0..10).random()
1
Willi Mentzel

拡張機能を作成することができます:

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

0

Kotlinでランダムな整数を取得するには、次の方法を使用します

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

お役に立てれば。

0
ARGeo