Home > OS >  Return a fixed sized list based on an other list
Return a fixed sized list based on an other list

Time:05-11

I am looking in Kotlin for a method who return me from a list a new list with a defined number of elements (for example 10). Whatever the size of the list, the method would always return the same number of elements.

For example, suppose a list of 3000 elements, it would return me a list of 10 elements from indexes 0, 300, 600, 900, 1200,...

Is there an extension function for this?

CodePudding user response:

Here's an idea:

Take advantage of the method chunked(size: Int), which tries to depart a given collection into sub-collections of the given size.
That's not quite what you want, but you can use it in order to implement a custom extension function which does what you want, e.g. like this:

fun List<Int>.departInto(subListCount: Int) : List<List<Int>> {
    // calculate the chunk size based on the desired amount of sublists
    val chunkSize = this.size / subListCount
    // then apply that value to the chunked method and return the result
    return this.chunked(chunkSize)
}

Using this could look as follows:

fun main() {
    // define some example list (of 30 elements in this case)
    val someList: List<Int> = List(30, {it})
    // use the extension function 
    val tenSubLists = someList.departInto(10)
    // print the result(s)
    println(tenSubLists)
}

The output of this code will be 10 sub-lists of 3 elements (your example of 3000 elements would then result in 10 sub-lists of 300 elements each):

[[0, 1, 2], [3, 4, 5], [6, 7, 8], [9, 10, 11], [12, 13, 14], [15, 16, 17], [18, 19, 20], [21, 22, 23], [24, 25, 26], [27, 28, 29]]

CodePudding user response:

That's kind of a specialised thing, so there's nothing (that I know of) in the standard library - but you could easily make your own extension function:

fun <T: Any> List<T>.sample2(count: Int): List<T> {
    // this allows for a fractional step, so we get a more accurate distribution of indices 
    // with smaller lists (where count doesn't divide into the list size evenly)
    val step = size / count.toFloat()
    return List(count) { i -> elementAt((i * step).toInt()) }
}

You'll get repeats if your list is too small to provide count unique indices (e.g. your list has 9 items and you want 10), so you'd have to handle that if you want different behaviour, but I think this is the easiest way to do it

  • Related