답변:
내 제안은 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()
.
KotlinJ 및 기타 변형
의 사용을 허용하지 않는 kotlinjs 및 기타 사용 사례 java.util.Random
에 대해서는 이 대안을 참조하십시오 .
또한 내 제안의 변형에 대해서는이 답변 을 참조하십시오 . 또한 임의 Char
의 확장 기능도 포함합니다 .
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
다음과 같은 확장 기능을 정의 할 수 있습니다
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 Random을 활용
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 Linear Congruential Generator를 구현합니다 . LCG는에서 사용하는 알고리즘 java.util.Random
입니다. 사용하려면이 링크를 따르십시오 :
https://gist.github.com/11e5ddb567786af0ed1ae4d7f57441d4
nextInt(range: IntRange)
당신을위한 나의 구현 목적 ;).
LCG는 대부분의 사용 사례 (시뮬레이션, 게임 등)에 적합하지만이 방법의 예측 가능성으로 인해 암호 사용에는 적합하지 않습니다.
더 이상 사용자 정의 확장 기능을 사용할 필요가 없습니다. IntRange 는 이제 즉시 사용할 수 있는 random()
확장 기능을 가지고 있습니다.
val randomNumber = (0..10).random()
먼저 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 진수이고 안드로이드 및 kotlin을 사용하는 16 진수 키 또는 mac 주소를 생성하려는 상황이있을 때마다 아래 코드가 도움이됩니다.
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
.