我经常遇到这样的问题,我想从一个列表中收集值,直到一个值匹配,但我也需要匹配的值本身。虽然takeWhile
在这方面几乎是完美的,但它实际上不允许保留最后一个(或基本上匹配的)条目。
举个简单的例子:显示对象的类层次结构,直到实现特定接口的第一个类
generateSequence(obj::class.java, Class<*>::getSuperclass)
.takeWhile { interestedType !in it.interfaces }
.joinToString(" > ")
.run(::println)
对于obj=arrayListOf(1)
和interestedType=Collection::class.java
,我希望看到如下内容:
class java.util.ArrayList > class java.util.AbstractList > class java.util.AbstractCollection
我希望它会像这样简单:
generateSequence(obj::class.java, Class<*>::getSuperclass)
.takeWhileInclusive { interestedType !in it.interfaces }
.joinToString(" > ")
.run(::println)
但是这样的函数并不存在(还没有?)。但是也许有其他的函数真的很接近这个函数?或者也许最多连续调用两次函数,它就已经很容易实现了,我只是没有看到它?
我不想找的:我如何解决关于层次结构中的哪个类实现接口的特定问题。这只是一个简单的例子。我也没有寻找:如何使用Iterator
或基本的while-/for-loop实现它...(除了:如果它容易阅读,并且不超过3行,那么...也许;- )).
我发现:Is this implementation of takeWhileInclusive safe?也链接了它自己的takeWhileInclusive
的实现(和它的灵感)。然而,我真的不喜欢它使用var
来注册它是否找到了匹配......当我读到评论(“假设顺序”)时,我也有点不确定这个实现是否真的有意义/真的安全。
2条答案
按热度按时间mqxuamgl1#
我还没有找到合适的现有函数,我也不太喜欢链接的解决方案,所以我玩了一下,最终得到了以下扩展函数:
它使用
sequence
,在需要时缓慢地产生值。至少我可以省略中间的var
,我认为这样可能更有益...ffvjumwh2#
遗憾的是,
takeWhile
使用的几个函数是内部的。但是如果我们将它们复制到扩展文件中,我们也可以为流构建takeWhileInclusive
:我不喜欢Kotlin内部代码的复制粘贴,但还没有找到更好的方法来实现它。