Is there a function in List that can achieve the u...
# getting-started
c
Is there a function in List that can achieve the uniform behavior of String
removeSuffix
or
removePrefix
?
It seems that there is no, eventually solved by creating an extension function:
Copy code
fun <T> List<T>.endsWith(vararg slice: T) = this.toList().takeLast(slice.size) == slice.toList()

fun <T> List<T>.removeSuffix(vararg suffix: T) =
  if (endsWith(*suffix)) this.dropLast(suffix.size) else this
I hope this can help others.
e
one possibly interesting alternative: it can be implemented on Sequence, lazily:
Copy code
fun <T> Sequence<T>.removeSuffix(vararg slice: T): Sequence<T> {
    require(slice.isNotEmpty())
    return sequence {
        val iter = this@removeSuffix.windowed(slice.size).iterator()
        if (!iter.hasNext()) return@sequence
        while (true) {
            val window = iter.next()
            if (iter.hasNext()) {
                yield(window.first())
            } else {
                if (window != slice.asList()) yieldAll(window)
                break
            }
        }
    }
}
c
windowed
operator I have not touched yet, I will go see! Very interesting
e
actually what I wrote has a bug in that if the slice is longer than the sequence it returns nothing. could be fixed at the cost of some complexity. anyway, your original extensions do work on eager Lists
cheers 1
j
Why
this.toList()
before calling
takeLast()
though? It's already a list, and creating a new instance doesn't seem to serve any purpose here
k
Also, @ephemient’s
require(slice.isNotEmpty())
shouldn't be needed, as
"xyz".endsWith("")
is allowed (returns true).
c
@Joffrey You are right, it is a redundant code
e
it's there because
.windowed(0)
is nonsense. that case should probably be handled separately.