Kotlin 如何找到第一个元素的方法结果不是null?

Kotlin 如何找到第一个元素的方法结果不是null?,kotlin,Kotlin,所以我有解析器,希望使用第一个返回非null值的解析器。我怎样才能做到最优雅呢 return parsers.map { it.parse(content) }.firstOrNull { it != null } 你会画出所有的百万吗?在选择第一个之前进行语法分析 return parsers.firstOrNull { it.parse(content) != null }?.parse(content) 会运行昂贵的?再次解析 我知道我可以 for (parser in parsers

所以我有解析器,希望使用第一个返回非null值的解析器。我怎样才能做到最优雅呢

return parsers.map { it.parse(content) }.firstOrNull { it != null }
你会画出所有的百万吗?在选择第一个之前进行语法分析

return parsers.firstOrNull { it.parse(content) != null }?.parse(content)
会运行昂贵的?再次解析

我知道我可以

for (parser in parsers) {
    val result = parser.parse(content)
    if (result != null) {
        return result
    }
}
return null
这是我能找到的最短的,但它不好读


我很确定这里有一个我看不到的快捷方式。

使用序列。它使您的计算变得懒惰,因此您只需要根据需要多次计算解析

return parsers.asSequence()
              .map { it.parse(content) }
              .find { it != null }

此外,您还可以使用以下代码:

parsers.asSequence()
    .mapNotNull { it.parse(content) }
    .first()

作为序列开销或不必要地映射大量值的替代方法,您可以使用扩展方法,例如:

inline fun <T, R> List<T>.firstMappedNotNull(transform: (T) -> R): R? {
    for (e in this)
        return transform(e) ?: continue
    return null
}
这使用了最少的映射函数调用和临时对象。它必须以命令式的方式编写,但它非常简短,并且使您自己的代码简短、清晰、功能强大

如果列表为空或每个映射都返回null,则此版本将返回null。当然,您可以更改签名和最后一行以引发异常


遗憾的是,这个函数还没有出现在标准库中。但是添加自己的函数很容易

太棒了!我的工具箱里肯定没有序列。我会让其他人在明天之前想出一些方法来解决这个问题,但我已经喜欢上了我丢失的工具。我最终使用了@gromyk的解决方案,因为它稍微短了一点,并且更明确地说明了如果不扔,就不要扔了!=null没有实现,但由于您是第一个提出序列并实际解释内容的人,所以您的答案是。谢谢……简短、清晰、实用。。。但不适用于功能实现本身;-如果转换结果为null,continue优先于return?这,虽然你接受T->R?使用elvis运算符回退?;-。。。但我喜欢你省略了顺序-我认为命名是这样一个函数最大的问题。此外,一旦你让它更通用,例如接受一个谓词而不是假设每个人都想返回第一个映射的非空值,那么使用它就会变得更麻烦。。。inline fun Iterable.findMappedtransform:T->R?,谓词:R?->布尔值:R。。。使用inline fun Iterable.findMappedNotNulltransform:T->R?=findMappedtransform{it!=null}?六羟甲基三聚氰胺六甲醚。。。。除了你过载了所有需要的功能…谢谢你的建议。对于一次过的事情,这是过分的,但我会记住,如果模式返回。
inline fun <T, R> List<T>.firstMappedNotNull(transform: (T) -> R): R? {
    for (e in this)
        return transform(e) ?: continue
    return null
}