Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Get a random item from list using kotlin streams

Tags:

random

kotlin

How to get a random item from a list in an easy and concise way.
ex: if I want to get an even random number from this list that.

val list = listOf(1, 2, 3, 4, 5, 6, 7, 9).filter { it % 2 == 0 } 

Note:
I know there are some similar answers in java that solves this problem but I think we can have a more concise way in kotlin.

like image 207
humazed Avatar asked Dec 16 '17 21:12

humazed


People also ask

How do you get items from kotlin list?

For retrieving an element at a specific position, there is the function elementAt() . Call it with the integer number as an argument, and you'll receive the collection element at the given position. The first element has the position 0 , and the last one is (size - 1) .

How do you randomly get elements from a list?

In Python, you can randomly sample elements from a list with choice() , sample() , and choices() of the random module. These functions can also be applied to a string and tuple. choice() returns one random element, and sample() and choices() return a list of multiple random elements.


2 Answers

Kotlin 1.3 and above:

Kotlin 1.3 is now available with Multiplatform Random Number Generator! You can use it like this :

import kotlin.random.Random  fun main() {     println(Random.nextBoolean())     println(Random.nextInt()) } 

Try it online!

or in your case

fun main() {     val list = (1..9).filter { it % 2 == 0 }     println(list.random()) } 

Try it online!


Kotlin 1.2

Since Kotlin 1.2, we have Iterable.shuffled(). This method could help you with the use of List.take() to extract the number of element you want (only one in this example).

val list = (1..9).filter { it % 2 == 0 } return list.shuffled().take(1)[0] 

This method is less optimized than before 1.2 one but it work on multiplatform context. Use the one you need according to your context.


Before Kotlin 1.2

Before Kotlin 1.2, no solution exists on a Multiplatform context to generate Random Number. The most easy solution is to call the Platform Random directly.

JVM

On the JVM we use Random or even ThreadLocalRandom if we're on JDK > 1.6.

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

JS

On the JS, we use Math.Random.

fun IntRange.random() = (Math.random() * ((endInclusive + 1) - start) + start).toInt() 
like image 177
Valentin Michalak Avatar answered Sep 23 '22 04:09

Valentin Michalak


I think the easiest and the most concise way is to create extension function that returns a random element so it can be used this way:

val random = list.random() 

the extension function:

/**  * Returns a random element.  */ fun <E> List<E>.random(): E? = if (size > 0) get(Random().nextInt(size)) else null 

thanks to @Francesco comment here is another function that takes a Random instance as the source of randomness

/**  * Returns a random element using the specified [random] instance as the source of randomness.  */ fun <E> List<E>.random(random: java.util.Random): E? = if (size > 0) get(random.nextInt(size)) else null 
like image 39
humazed Avatar answered Sep 24 '22 04:09

humazed