A generic method that can return a random integer between 2 parameters like ruby does with rand(0..n)
.
Any suggestion?
A generic method that can return a random integer between 2 parameters like ruby does with rand(0..n)
.
Any suggestion?
My suggestion would be an extension function on IntRange to create randoms like this: (0..10).random()
As of 1.3, Kotlin comes with its own multi-platform Random generator. It is described in this KEEP. The extension described below is now part of the Kotlin standard library, simply use it like this:
val rnds = (0..10).random()
Before 1.3, on the JVM we use Random
or even ThreadLocalRandom
if we're on JDK > 1.6.
fun IntRange.random() =
Random().nextInt((endInclusive + 1) - start) + start
Used like this:
// will return an `Int` between 0 and 10 (incl.)
(0..10).random()
If you wanted the function only to return 1, 2, ..., 9
(10
not included), use a range constructed with until
:
(0 until 10).random()
If you're working with JDK > 1.6, use ThreadLocalRandom.current()
instead of Random()
.
For kotlinjs and other use cases which don't allow the usage of java.util.Random
, see this alternative.
Also, see this answer for variations of my suggestion. It also includes an extension function for random Char
s.
Generate a random integer between from
(inclusive) and to
(exclusive)
import java.util.Random
val random = Random()
fun rand(from: Int, to: Int) : Int {
return random.nextInt(to - from) + from
}
As of kotlin 1.2, you could write:
(1..3).shuffled().last()
Just be aware it's big O(n), but for a small list (especially of unique values) it's alright :D
You can create an extension function similar to java.util.Random.nextInt(int)
but one that takes an IntRange
instead of an Int
for its bound:
fun Random.nextInt(range: IntRange): Int {
return range.start + nextInt(range.last - range.start)
}
You can now use this with any Random
instance:
val random = Random()
println(random.nextInt(5..9)) // prints 5, 6, 7, or 8
If you don't want to have to manage your own Random
instance then you can define a convenience method using, for example, ThreadLocalRandom.current()
:
fun rand(range: IntRange): Int {
return ThreadLocalRandom.current().nextInt(range)
}
Now you can get a random integer as you would in Ruby without having to first declare a Random
instance yourself:
rand(5..9) // returns 5, 6, 7, or 8
Possible Variation to my other answer for random chars
In order to get random Char
s, you can define an extension function like this
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()
If you're working with JDK > 1.6, use ThreadLocalRandom.current()
instead of Random()
.
For kotlinjs and other use cases which don't allow the usage of java.util.Random
, this answer will help.
As of 1.3, Kotlin comes with its own multiplatform Random generator. It is described in this KEEP. You can now directly use the extension as part of the Kotlin standard library without defining it:
('a'..'b').random()
Building off of @s1m0nw1 excellent answer I made the following changes.
Code:
private object RandomRangeSingleton : Random()
fun ClosedRange<Int>.random() = RandomRangeSingleton.nextInt((endInclusive + 1) - start) + start
Test Case:
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())
}
)
}
Examples random in the range [1, 10]
val random1 = (0..10).shuffled().last()
or utilizing Java Random
val random2 = Random().nextInt(10) + 1
As of 1.3, the standard library provided multi-platform support for randoms, see this answer.
If you are working with Kotlin JavaScript and don't have access to java.util.Random
, the following will work:
fun IntRange.random() = (Math.random() * ((endInclusive + 1) - start) + start).toInt()
Used like this:
// will return an `Int` between 0 and 10 (incl.)
(0..10).random()
Another way of implementing s1m0nw1's answer would be to access it through a variable. Not that its any more efficient but it saves you from having to type ().
var ClosedRange<Int>.random: Int
get() { return Random().nextInt((endInclusive + 1) - start) + start }
private set(value) {}
And now it can be accessed as such
(1..10).random
Using a top-level function, you can achieve exactly the same call syntax as in Ruby (as you wish):
fun rand(s: Int, e: Int) = Random.nextInt(s, e + 1)
Usage:
rand(1, 3) // returns either 1, 2 or 3
First, you need a RNG. In Kotlin you currently need to use the platform specific ones (there isn't a Kotlin built in one). For the JVM it's java.util.Random
. You'll need to create an instance of it and then call random.nextInt(n)
.
There is no standard method that does this but you can easily create your own using either Math.random()
or the class java.util.Random
. Here is an example using the Math.random()
method:
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) })
}
This is a sample output:
[9, 8, 1, 7, 5, 6, 9, 8, 1, 9]
[5, 8, 9, 7, 6, 6, 8, 6, 7, 9]
Kotlin standard lib doesn't provide Random Number Generator API. If you aren't in a multiplatform project, it's better to use the platform api (all the others answers of the question talk about this solution).
But if you are in a multiplatform context, the best solution is to implement random by yourself in pure kotlin for share the same random number generator between platforms. It's more simple for dev and testing.
To answer to this problem in my personal project, i implement a pure Kotlin Linear Congruential Generator. LCG is the algorithm used by java.util.Random
. Follow this link if you want to use it :
https://gist.github.com/11e5ddb567786af0ed1ae4d7f57441d4
My implementation purpose nextInt(range: IntRange)
for you ;).
Take care about my purpose, LCG is good for most of the use cases (simulation, games, etc...) but is not suitable for cryptographically usage because of the predictability of this method.
If the numbers you want to choose from are not consecutive, you can use random()
.
Usage:
val list = listOf(3, 1, 4, 5)
val number = list.random()
Returns one of the numbers which are in the list.
In Kotlin 1.3 you can do it like
val number = Random.nextInt(limit)
No need to use custom extension functions anymore. IntRange has a random()
extension function out-of-the-box now.
val randomNumber = (0..10).random()
To get a random Int number in Kotlin use the following method:
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
Hope this helps.
to be super duper ))
fun rnd_int(min: Int, max: Int): Int {
var max = max
max -= min
return (Math.random() * ++max).toInt() + min
}