Kotlin'de rastgele bir sayıyı nasıl alabilirim?


151

Ruby gibi 2 parametre arasında rastgele bir tamsayı döndürebilen genel bir yöntem rand(0..n).

Herhangi bir öneri?

Yanıtlar:


375

Benim önerim böyle rasgele oluşturmak için IntRange bir uzantı işlevi olacaktır :(0..10).random()

TL; DR Kotlin> = 1.3, tüm platformlar için bir Rastgele

1.3'ten itibaren Kotlin kendi çoklu platform Rastgele jeneratörü ile birlikte geliyor. Bu KEEP'te açıklanmaktadır . Aşağıda açıklanan uzantı şimdi Kotlin standart kütüphanesinin bir parçası , sadece şu şekilde kullanın:

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

Kotlin <1.3

1.3'ten önce, kullandığımız JVM'de Randomveya ThreadLocalRandomJDK> 1.6'da olsak bile .

fun IntRange.random() = 
       Random().nextInt((endInclusive + 1) - start) + start

Bunun gibi kullanılır:

// will return an `Int` between 0 and 10 (incl.)
(0..10).random()

İşlevin yalnızca geri dönmesini 1, 2, ..., 9( 10dahil edilmedi) istiyorsanız , aşağıdakilerle oluşturulmuş bir aralık kullanın until:

(0 until 10).random()

JDK> 1.6 ile çalışıyorsanız, ThreadLocalRandom.current()yerine kullanın Random().

KotlinJs ve diğer varyasyonlar

Kotlinjs ve kullanımına izin vermeyen diğer kullanım durumları java.util.Randomiçin bu alternatife bakın .

Ayrıca, önerimin varyasyonları için bu cevaba bakınız . Ayrıca rastgele Chars için bir genişletme işlevi içerir .


Bu Java'nın da kullandığını varsayalım java.util.Random?
Simon Forsberg

@SimonForsberg Gerçekten.
Yararlanmayan

Burada ayrıca Kriptografik Olarak Güvenli Sahte Rastgele Sayı Üreticisi (CSPRNG) eklemek için bir teklif var: github.com/Kotlin/KEEP/issues/184
Jonathan Leitschuh 19:19

41

from(Kapsayıcı) ve to(özel) arasında rastgele bir tamsayı oluşturun

import java.util.Random

val random = Random()

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

1
Birkaç aralıklı rastgele Ints almak istiyorsanız , java-8 yerine Random # int (boyut, 'den,' e) kullanabilirsiniz .
holi-java

3
Bu çözüm Javascript / Native Kotlin üzerinde çalışmaz. Belki de bunu yapmak için daha genel bir yöntem yapmak harika olabilir. :)
Valentin Michalak

@ValentinMichalak bunu deneyebilirsiniz: stackoverflow.com/a/49507413/8073652
s1m0nw1

31

Kotlin 1.2'den itibaren şunları yazabilirsiniz:

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

Sadece büyük O (n) olduğunu unutmayın, ancak küçük bir liste için (özellikle benzersiz değerlerde) sorun yok: D


Bu kotlin-native için kullanışlıdır
user3471194

11

Sınırı için yerine bir yerine benzer bir uzantı işlevi oluşturabilirsiniz :java.util.Random.nextInt(int)IntRangeInt

fun Random.nextInt(range: IntRange): Int {
    return range.start + nextInt(range.last - range.start)
}

Artık bunu herhangi bir Randomörnekle kullanabilirsiniz:

val random = Random()
println(random.nextInt(5..9)) // prints 5, 6, 7, or 8

Kendi Randomörneğinizi yönetmek istemiyorsanız, aşağıdakileri kullanarak bir kolaylık yöntemi tanımlayabilirsiniz ThreadLocalRandom.current():

fun rand(range: IntRange): Int {
    return ThreadLocalRandom.current().nextInt(range)
}

Şimdi bir Randomörneği kendiniz bildirmek zorunda kalmadan Ruby'de yaptığınız gibi rastgele bir tam sayı elde edebilirsiniz :

rand(5..9) // returns 5, 6, 7, or 8

10

Rasgele karakterler için diğer cevabımda olası varyasyon

Rastgele Chars elde etmek için , böyle bir uzantı işlevi tanımlayabilirsiniz

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 ile çalışıyorsanız, ThreadLocalRandom.current() yerine kullanın Random().

Kullanımı izin vermez kotlinjs ve diğer kullanım durumları için java.util.Random, bu cevap yardımcı olacaktır.

Kotlin> = 1.3 Random için çoklu platform desteği

1.3'ten itibaren Kotlin kendi çoklu platform Rastgele jeneratörü ile birlikte geliyor. Bu KEEP'te açıklanmaktadır . Artık uzantıyı tanımlamaksızın doğrudan Kotlin standart kütüphanesinin bir parçası olarak kullanabilirsiniz:

('a'..'b').random()

7

Off Bina @ s1m0nw1 mükemmel cevap aşağıdaki değişiklikleri yaptı.

  1. (0..n) Kotlin dahil
  2. (N'ye kadar 0) Kotlin'de münhasır anlamına gelir
  3. Rastgele örnek için tek bir nesne kullanın (isteğe bağlı)

Kod:

private object RandomRangeSingleton : Random()

fun ClosedRange<Int>.random() = RandomRangeSingleton.nextInt((endInclusive + 1) - start) + start

Test durumu:

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

5

[1, 10] aralığında rastgele örnekler

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

Java Random'ı kullanma veya kullanma

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

1
İlk cevabını en çok seviyorum. Herhangi bir uzatma işlevi yazmak için gerekli olmayan mükemmel bir tek astar
Alex Semeniuk

4

Kotlin> = 1.3, Random için çoklu platform desteği

1.3'ten itibaren standart kütüphane rasgele çoklu platform desteği sağladı, bu cevaba bakınız .

Kotlin <1.3 JavaScript hakkında

Kotlin JavaScript ile çalışıyorsanız ve erişiminiz yoksa java.util.Random, aşağıdakiler işe yarar :

fun IntRange.random() = (Math.random() * ((endInclusive + 1) - start) + start).toInt()

Bunun gibi kullanılır:

// will return an `Int` between 0 and 10 (incl.)
(0..10).random()

4

S1m0nw1'in cevabını uygulamanın başka bir yolu da ona bir değişken aracılığıyla erişmek olacaktır. Bu onun daha verimli değil ama () yazmak zorunda kalmaz.

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

Ve şimdi bu şekilde erişilebilir

(1..10).random

3

Kotlin 1.3'te şöyle yapabilirsiniz

val number = Random.nextInt(limit)

2

Bunu yapan standart bir yöntem yoktur, ancak Math.random()sınıflardan birini veya sınıfını kullanarak kendi yönteminizi kolayca oluşturabilirsiniz java.util.Random. İşte Math.random()yöntemi kullanan bir örnek :

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

Bu bir örnek çıktıdır:

[9, 8, 1, 7, 5, 6, 9, 8, 1, 9]
[5, 8, 9, 7, 6, 6, 8, 6, 7, 9]

2

Kotlin standart lib Rastgele Sayı Üreticisi API'sı sağlamaz. Çok platformlu bir projede değilseniz, platform api'sini kullanmak daha iyidir (diğer tüm soruların cevapları bu çözüm hakkında konuşur) .

Ancak çok platformlu bir bağlamdaysanız, en iyi çözüm, platformlar arasında aynı rasgele sayı üreticisini paylaşmak için saf kotlin'de rastgele kendiniz uygulamaktır. Geliştirme ve test için daha basit.

Kişisel projemdeki bu soruna cevap vermek için saf bir Kotlin Linear Congruential Generator uyguluyorum . LCG, tarafından kullanılan algoritmadır java.util.Random. Kullanmak istiyorsanız bu bağlantıyı izleyin: https://gist.github.com/11e5ddb567786af0ed1ae4d7f57441d4

nextInt(range: IntRange)Sizin için uygulama amacım ;).

Amacımla ilgilen, LCG çoğu kullanım durumu için (simülasyon, oyunlar vb.) İyidir, ancak bu yöntemin öngörülebilirliği nedeniyle kriptografik kullanım için uygun değildir.


Kendi rastgele algoritmamı yapmak yerine platforma özel koda güvenmeyi tercih ederim. Bu bana java.util.Random kodunu hatırlatıyor, ancak tamamen eşleşmiyor.
Simon Forsberg

2

Aralarından seçim yapmak istediğiniz numaralar ardışık değilse, kullanabilirsiniz random().

Kullanımı:

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

Listedeki numaralardan birini döndürür.


2

Artık özel uzantı işlevlerini kullanmaya gerek yok. IntRange artık kullanıma hazır bir random()uzantı işlevine sahip .

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

2

Üst düzey bir işlev kullanarak, Ruby'deki ile tam olarak aynı çağrı sözdizimini (istediğiniz gibi) elde edebilirsiniz:

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

Kullanımı:

rand(1, 3) // returns either 1, 2 or 3

1

İlk olarak, bir RNG'ye ihtiyacınız var. Kotlin'de şu anda platforma özel olanları kullanmanız gerekiyor (birinde bir Kotlin yok). JVM için öyle java.util.Random. Bunun bir örneğini oluşturmanız ve sonra aramanız gerekir random.nextInt(n).


1

Kotlin'de rastgele bir Int numarası almak için aşağıdaki yöntemi kullanın :

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

Bu yardımcı olur umarım.


0

Bir uzantı işlevi oluşturabilirsiniz:

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

Yuvarlak şamandıra değeri:

fun Float.round(decimals: Int = DIGITS): Float {
    var multiplier = 1.0f
    repeat(decimals) { multiplier *= 10 }
    return round(this * multiplier) / multiplier
}

Yöntemin kullanımı:

(0.0f .. 1.0f).step(.1f).forEach { System.out.println("value: $it") }

Çıktı:

değer: 0.0 değer: 0.1 değer: 0.2 değer: 0.3 değer: 0.4 değer: 0.5 değer: 0.6 değer: 0.7 değer: 0.8 değer: 0.9 değer: 1.0


0

Tam kaynak kodu. Kopyalara izin verilip verilmediğini kontrol edebilir.

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

0

Kullanıcı talebine göre basamaklı onaltılık sayı olan anahtar veya mac adresi oluşturmak istediğinizde ve android ve kotlin kullanarak da bir durum olduğunda, aşağıdaki kodum size yardımcı olur:

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

-1

süper kandırıcı olmak))

 fun rnd_int(min: Int, max: Int): Int {
        var max = max
        max -= min
        return (Math.random() * ++max).toInt() + min
    }
Sitemizi kullandığınızda şunları okuyup anladığınızı kabul etmiş olursunuz: Çerez Politikası ve Gizlilik Politikası.
Licensed under cc by-sa 3.0 with attribution required.