Often I see the problem that I want to collect values from a list until a value matches, but where I also need the matching value itself. While takeWhile
is nearly perfect for that matter, it actually doesn't allow keeping the last (or basically the matching) entry.
A simple example: show the class hierarchy of an object up to the first class that implements a specific interface
generateSequence(obj::class.java, Class<*>::getSuperclass)
.takeWhile { interestedType !in it.interfaces }
.joinToString(" > ")
.run(::println)
for obj=arrayListOf(1)
and interestedType=Collection::class.java
I want to see something like:
class java.util.ArrayList > class java.util.AbstractList > class java.util.AbstractCollection
and I hoped it would be as easy as:
generateSequence(obj::class.java, Class<*>::getSuperclass)
.takeWhileInclusive { interestedType !in it.interfaces }
.joinToString(" > ")
.run(::println)
But such a function doesn't exist (yet?). But maybe there is some other function that really comes close to that? Or maybe with at most 2 consecutive function calls it is already easily implementable and I just don't see it?
What I am not looking for: how I can solve that particular issue regarding which class in the hierarchy implements an interface. That's just a simple example. What I am also not looking for: how I can implement that with Iterator
or a basic while-/for-loop... (except: if it is easily readable and doesn't take more than 3 lines then... maybe ;-)).
What I found: Is this implementation of takeWhileInclusive safe? which also links its own implementation (and its inspiration) for takeWhileInclusive
. However I don't really like that it's using the var
to register whether it found a match... I also am a bit unsure when I read the comments ("assume sequential order") whether this implementation really makes sense/really is safe.