回答:
私の提案は、次のようなランダムを作成するためのIntRangeの拡張関数です。(0..10).random()
1.3以降、Kotlinには独自のマルチプラットフォームランダムジェネレーターが付属しています。このKEEPで説明されています。以下で説明する拡張機能は、Kotlin標準ライブラリの一部になりました。次のように使用してください。
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とその他のバリエーション
kotlinjsや、の使用を許可しないその他の使用例java.util.Random
については、この代替方法をご覧ください。
また、私の提案のバリエーションについては、この回答を参照してください。また、ランダムChar
sの拡張関数も含まれています。
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)
}
これで、最初にRandom
インスタンスを自分で宣言しなくても、Rubyの場合と同じようにランダムな整数を取得できます。
rand(5..9) // returns 5, 6, 7, or 8
ランダムな文字に関する他の回答に対するバリエーションの可能性
ランダムな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.6で作業している場合は、のThreadLocalRandom.current()
代わりにを使用してくださいRandom()
。
kotlinjsや、の使用を許可しないその他の使用例ではjava.util.Random
、この回答が役立ちます。
1.3以降、Kotlinには独自のマルチプラットフォームランダムジェネレーターが付属しています。このKEEPで説明されています。拡張機能を定義せずに、Kotlin標準ライブラリの一部として直接使用できるようになりました。
('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ランダムを利用する
val random2 = Random().nextInt(10) + 1
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()
これを行う標準メソッドはありませんが、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]
Kotlin標準ライブラリは、乱数ジェネレータAPIを提供していません。マルチプラットフォームプロジェクトに参加していない場合は、プラットフォームAPIを使用することをお勧めします(この質問に対する他のすべての回答は、このソリューションについて話しています)。
ただし、マルチプラットフォームのコンテキストを使用している場合、最善の解決策は、純粋なkotlinに自分でランダムに実装して、プラットフォーム間で同じ乱数ジェネレータを共有することです。開発とテストの方が簡単です。
私の個人的なプロジェクトでこの問題に答えるために、私は純粋なKotlin 線形合同ジェネレーターを実装します。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()
リストにある数値の1つを返します。
トップレベルの関数を使用すると、Rubyとまったく同じ呼び出し構文を実現できます(希望どおり)。
fun rand(s: Int, e: Int) = Random.nextInt(s, e + 1)
使用法:
rand(1, 3) // returns either 1, 2 or 3
まず、RNGが必要です。Kotlinでは現在、プラットフォーム固有のプラットフォームを使用する必要があります(組み込みのKotlinはありません)。JVMの場合はjava.util.Random
です。そのインスタンスを作成してからを呼び出す必要がありますrandom.nextInt(n)
。
Kotlinでランダムな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("")
}
}
}
ユーザーの要求に基づいて数字を持つ16進数のキーまたは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()
}
java.util.Random
思いますか?