Um método genérico que pode retornar um número inteiro aleatório entre 2 parâmetros, como o ruby faz com rand(0..n)
.
Alguma sugestão?
Um método genérico que pode retornar um número inteiro aleatório entre 2 parâmetros, como o ruby faz com rand(0..n)
.
Alguma sugestão?
Respostas:
Minha sugestão seria uma função de extensão no IntRange para criar randoms como este:(0..10).random()
A partir da versão 1.3, o Kotlin vem com seu próprio gerador aleatório multiplataforma. É descrito neste KEEP . A extensão descrita abaixo agora faz parte da biblioteca padrão do Kotlin , basta usá-la assim:
val rnds = (0..10).random()
Antes da versão 1.3, na JVM, usamos Random
ou mesmo ThreadLocalRandom
no JDK> 1.6.
fun IntRange.random() =
Random().nextInt((endInclusive + 1) - start) + start
Usado assim:
// will return an `Int` between 0 and 10 (incl.)
(0..10).random()
Se você deseja que a função retorne apenas 1, 2, ..., 9
( 10
não incluída), use um intervalo construído com until
:
(0 until 10).random()
Se você estiver trabalhando com JDK> 1.6, use em ThreadLocalRandom.current()
vez de Random()
.
KotlinJs e outras variações
Para kotlinjs e outros casos de uso que não permitem o uso java.util.Random
, consulte esta alternativa .
Além disso, veja esta resposta para obter variações de minha sugestão. Também inclui uma função de extensão para Char
s aleatórios .
Gere um número inteiro aleatório entre from
(inclusive) e to
(exclusivo)
import java.util.Random
val random = Random()
fun rand(from: Int, to: Int) : Int {
return random.nextInt(to - from) + from
}
Int
s aleatórios à distância , use Random # int (tamanho, de, até) em java-8 .
No kotlin 1.2, você poderia escrever:
(1..3).shuffled().last()
Esteja ciente de que é grande O (n), mas para uma pequena lista (especialmente de valores únicos) está tudo bem: D
Você pode criar uma função de extensão semelhante a java.util.Random.nextInt(int)
uma que aceita um em IntRange
vez de um Int
para seu limite:
fun Random.nextInt(range: IntRange): Int {
return range.start + nextInt(range.last - range.start)
}
Agora você pode usar isso com qualquer Random
instância:
val random = Random()
println(random.nextInt(5..9)) // prints 5, 6, 7, or 8
Se você não deseja gerenciar sua própria Random
instância, pode definir um método de conveniência usando, por exemplo ThreadLocalRandom.current()
:
fun rand(range: IntRange): Int {
return ThreadLocalRandom.current().nextInt(range)
}
Agora você pode obter um número inteiro aleatório como faria no Ruby sem precisar primeiro declarar uma Random
instância:
rand(5..9) // returns 5, 6, 7, or 8
Possível variação da minha outra resposta para caracteres aleatórios
Para obter Char
s aleatórios , você pode definir uma função de extensão como esta
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()
Se você estiver trabalhando com JDK> 1.6, use em ThreadLocalRandom.current()
vez de Random()
.
Para kotlinjs e outros casos de uso que não permitem o uso java.util.Random
, esta resposta ajudará.
A partir da versão 1.3, o Kotlin vem com seu próprio gerador aleatório multiplataforma. É descrito neste KEEP . Agora você pode usar diretamente a extensão como parte da biblioteca padrão do Kotlin sem defini-la:
('a'..'b').random()
Com base na resposta excelente do @ s1m0nw1, fiz as seguintes alterações.
Código:
private object RandomRangeSingleton : Random()
fun ClosedRange<Int>.random() = RandomRangeSingleton.nextInt((endInclusive + 1) - start) + start
Caso de teste:
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())
}
)
}
Exemplos aleatórios no intervalo [1, 10]
val random1 = (0..10).shuffled().last()
ou utilizando Java Random
val random2 = Random().nextInt(10) + 1
A partir da versão 1.3, a biblioteca padrão forneceu suporte multiplataforma para randoms, veja esta resposta.
Se você estiver trabalhando com o Kotlin JavaScript e não tiver acesso java.util.Random
, o seguinte funcionará:
fun IntRange.random() = (Math.random() * ((endInclusive + 1) - start) + start).toInt()
Usado assim:
// will return an `Int` between 0 and 10 (incl.)
(0..10).random()
Outra maneira de implementar a resposta de s1m0nw1 seria acessá-la através de uma variável. Não que seja mais eficiente, mas evita que você precise digitar ().
val ClosedRange<Int>.random: Int
get() = Random().nextInt((endInclusive + 1) - start) + start
E agora ele pode ser acessado como tal
(1..10).random
No Kotlin 1.3, você pode fazê-lo como
val number = Random.nextInt(limit)
Não existe um método padrão que faça isso, mas você pode facilmente criar o seu próprio usando Math.random()
a classe ou java.util.Random
. Aqui está um exemplo usando o Math.random()
método:
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) })
}
Esta é uma saída de amostra:
[9, 8, 1, 7, 5, 6, 9, 8, 1, 9]
[5, 8, 9, 7, 6, 6, 8, 6, 7, 9]
A lib padrão do Kotlin não fornece a API Random Number Generator. Se você não estiver em um projeto de multiplataforma, é melhor usar a API da plataforma (todas as outras respostas da pergunta falam sobre esta solução) .
Mas se você estiver em um contexto de multiplataforma, a melhor solução é implementar aleatoriamente sozinho no puro kotlin para compartilhar o mesmo gerador de números aleatórios entre plataformas. É mais simples para desenvolvedores e testes.
Para responder a esse problema no meu projeto pessoal, implementei um gerador de congruência linear Kotlin puro . LCG é o algoritmo usado por java.util.Random
. Siga este link se desejar usá-lo:
https://gist.github.com/11e5ddb567786af0ed1ae4d7f57441d4
Meu objetivo de implementação nextInt(range: IntRange)
para você;).
Tome cuidado com o meu objetivo, o LCG é bom para a maioria dos casos de uso (simulação, jogos, etc ...), mas não é adequado para uso criptográfico devido à previsibilidade desse método.
Se os números que você deseja escolher não forem consecutivos, você pode usar random()
.
Uso:
val list = listOf(3, 1, 4, 5)
val number = list.random()
Retorna um dos números que estão na lista.
Não é mais necessário usar funções de extensão personalizadas. O IntRange agora possui uma random()
função de extensão pronta para uso.
val randomNumber = (0..10).random()
Usando uma função de nível superior, você pode obter exatamente a mesma sintaxe de chamada que no Ruby (como desejar):
fun rand(s: Int, e: Int) = Random.nextInt(s, e + 1)
Uso:
rand(1, 3) // returns either 1, 2 or 3
Primeiro, você precisa de um RNG. No Kotlin, você atualmente precisa usar os específicos da plataforma (não há um Kotlin embutido em um). Para a JVM é java.util.Random
. Você precisará criar uma instância e depois chamar random.nextInt(n)
.
Para obter um número Int aleatório no Kotlin, use o seguinte método :
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
Espero que isto ajude.
Você pode criar uma função de extensão:
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()
}
Valor flutuante redondo:
fun Float.round(decimals: Int = DIGITS): Float {
var multiplier = 1.0f
repeat(decimals) { multiplier *= 10 }
return round(this * multiplier) / multiplier
}
Uso do método:
(0.0f .. 1.0f).step(.1f).forEach { System.out.println("value: $it") }
Resultado:
valor: 0.0 valor: 0.1 valor: 0.2 valor: 0.3 valor: 0.4 valor: 0.5 valor: 0.6 valor: 0.7 valor: 0.8 valor: 0.9 valor: 1.0
Código fonte completo. Pode controlar se duplicatas são permitidas.
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("")
}
}
}
Sempre que houver uma situação em que você queira gerar um endereço chave ou mac, que seja um número hexadecimal com dígitos com base na demanda do usuário e que também use o android e o kotlin, o código abaixo ajudará você:
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()
}
ser super duper))
fun rnd_int(min: Int, max: Int): Int {
var max = max
max -= min
return (Math.random() * ++max).toInt() + min
}
java.util.Random
?