Hildebrandt Tobias
05/08/2024, 9:02 AM.sublist that doesn't throw an OutOfBoundsException and just gives me all it can?
So if I say give me 4 elements from index 2 onwards, but the list has only 5 entries it should just give me back index 2, 3 and 4.Hildebrandt Tobias
05/08/2024, 9:08 AMmyList.sublist(n, myList.size-1).take(m)CLOVIS
05/08/2024, 9:15 AMfun <T> List<T>.safeSubList(from: Int, to: Int) =
subList(from.coerceIn(indices), to.coerceIn(indices.start, indices.last + 1))CLOVIS
05/08/2024, 9:15 AMSzymon Jeziorski
05/08/2024, 9:21 AMsize as follows:
subList(from.coerceAtLeast(0), to.coerceAtMost(size))CLOVIS
05/08/2024, 9:24 AMCLOVIS
05/08/2024, 9:24 AMSzymon Jeziorski
05/08/2024, 9:46 AMsubList(from.coerceIn(0..size), to.coerceAtLeast(max(from, 0)).coerceAtMost(size))
https://pl.kotl.in/DNMKJkDTsCLOVIS
05/08/2024, 9:47 AMsubList to behaveHildebrandt Tobias
05/08/2024, 9:59 AMsublist to throwHildebrandt Tobias
05/08/2024, 10:03 AMif(n < list.size) {
list.subList(n, state.stationList.size - 1).take(m)
}
But I'll probably add an extension function with SJ's answer.Gurgen Nersesyan
05/08/2024, 10:04 AMlist.drop(2) ? Or maybe I didn't get the questioHildebrandt Tobias
05/08/2024, 10:05 AMGurgen Nersesyan
05/08/2024, 10:05 AMHildebrandt Tobias
05/08/2024, 10:06 AMlist.drop(n).take(m)? Does that throw?Gurgen Nersesyan
05/08/2024, 10:06 AMGurgen Nersesyan
05/08/2024, 10:07 AMHildebrandt Tobias
05/08/2024, 10:07 AMCLOVIS
05/08/2024, 10:07 AMGurgen Nersesyan
05/08/2024, 10:09 AMlist.slice(n..m) will do, not sure if that throws or notGurgen Nersesyan
05/08/2024, 10:28 AMGurgen Nersesyan
05/08/2024, 10:29 AMGurgen Nersesyan
05/08/2024, 10:29 AMfun <T> List<T>.safeSubList(n: Int, m: Int): List<T> {
val start = min(max(n,0), min(m, this.size))
val end = min(max(start, m), this.size)
return this.subList(start, end)
}Gurgen Nersesyan
05/08/2024, 10:32 AMSzymon Jeziorski
05/08/2024, 10:33 AMList<T>.slice body looks like this:
if (indices.isEmpty()) return listOf()
return this.subList(indices.start, indices.endInclusive + 1).toList()
so it's not safe in case of index bounds, and also creates new list as a result.
One other thing to note is that resulting sublist from normal subList method reflects changes made to the original list, whereas drop, take etc create new lists with shallow copy of the data from original list.
So what you actually need depends on the context, I would put it like that:
Do you want sublist to reflect changes made to original list?
Yes:
Do you want implementation to be index safe?
Yes: proposed `list.safeSubList(from, to)`
No: `list.subList(from, to)`
No:
Do you want implementation to be index safe?
Yes:
Is the performance critical?
Yes: `list.safeSubList(from, to).toList()` // or even create yet another extension if you want to avoid SubList wrapping, though it should be cheap as it doesn't copy data
No: above or `take`/`takeLast` + `drop`/`dropLast` combo
No: `list.slice(from, to)`Szymon Jeziorski
05/08/2024, 10:46 AMtake / drop etc may not be affecting you much if you're working on relatively small collections. After all I would try to be pragmatic about it and think of it not only about in performance's aspect, but rather in wider context having readability and maintainability in mind (on the one hand dedicated extension can be super handy and make your life easier, but one the other, if you have a codebase with 200 of such micro extensions and use them all over the place then could just be an overkill making reading and writing code harder)