https://kotlinlang.org logo
#getting-started
Title
# getting-started
c

Colton Idle

06/27/2023, 9:38 PM
Is there a way to split a list in two at a given index? I tried
partition
but I can't give it a true/false predicate. I just want to give it a location. I tried
slice
but it only gives me a list after the index. I just wanna be able to slice a list into two parts at a given index and get both parts in one shot (that should be more performant than calling slice twice... right?)
y

Youssef Shoaib [MOD]

06/27/2023, 9:43 PM
Just use
sublist
twice. It returns a view on the list, and so it just results in an object allocation. Do keep in mind that sublist does depend on the list, and so if the list updates, the sublists would update, but that can be simply remedied by copying first before `sublist`ing
plus1 2
c

Colton Idle

06/27/2023, 9:46 PM
Thanks!
f

Francesc

06/27/2023, 10:38 PM
you can also use
take
and
drop
,
Copy code
val firstN = list.take(n)
val remainder = list.drop(n)
1
👌 1
p

Pihentagy

06/28/2023, 8:01 AM
What was the problem with slice?
Btw is there a way to create an unbounded range to avoid specifying list.size?
c

CLOVIS

06/28/2023, 8:44 AM
n until Int.MAX_VALUE
?
😒 1
k

Klitos Kyriacou

06/28/2023, 8:45 AM
That gives IndexOutOfBoundsException. It occurs to me that String has a substring function that takes one Int argument and returns the substring up to the end. Why is List different?
c

CLOVIS

06/28/2023, 8:45 AM
Ah, no,
slice
expects the end limit to be a valid index. Using
take
/`drop` is probably the best, then.
String has a substring function that takes one Int argument and returns the substring up to the end.
That's
List.drop
But yeah, String and List have a lot of differences.
length
/`size` ,
substring
/`subList` …
f

Fabrizio Scarponi

06/28/2023, 12:45 PM
@Pihentagy Follow upvoted solution or feel free to use a listIterator, and use the content while your are iterating, is will be probably the best effort solution
Copy code
list.listIterator()
    .withIndex()
    .forEachRemaining { (index, it) ->
        when {
            index < list.size / 2 -> println("first half")
            else -> println("second half")
        }
    }
m

Michael de Kaste

06/28/2023, 1:29 PM
This is why, locally, we have introduced the concept of
Copy code
val leftBound = n until null
val rightBound = null until n
val open = openRange<Int>() // null until null, typesafe
but I would love for these mathematical properties to exist in kotlin itself as well, we can't live without them
c

Colton Idle

06/28/2023, 1:32 PM
I know I can call slice twice or sublist twice. I was hoping there was a method that returned a pair with the first chunk of the list, and the second chunk of the list.
c

CLOVIS

06/28/2023, 1:33 PM
Copy code
fun <T> List<T>.partition(n: Int) =
    take(n) to drop(n)
Maybe it's worth making a feature request to the standard lib?
c

Colton Idle

06/28/2023, 1:34 PM
have never filed a feature request for kotlin. i might look that up.
c

CLOVIS

06/28/2023, 1:35 PM
Just explain what you want here: https://kotl.in/issue Do mention that you know about take/drop, but you'd like a function that does both at once.
If you do create it, please send the link here afterwards, I'd like to subscribe to it
k

Klitos Kyriacou

06/28/2023, 1:44 PM
I think this does what you want:
Copy code
list.withIndex().partition { it.index <= n }.toList().map { it.map { it.value } }
But it's so unreadable that any of the other solutions are better.
c

CLOVIS

06/29/2023, 6:40 AM
↑ it's also much slower: it goes through the list 2 times, whereas the take/drop solution doesn't even go through the list once
20 Views