kotlin - Kotlin 中序列的查找和转换

标签 kotlin functional-programming

我经常偶然发现这个问题,但没有看到一个常见的实现:我如何惯用地(功能上)找到一个元素,在匹配后停止搜索,并返回一个不同的类型(即映射任何匹配到另一种类型)?

我已经能够做一个解决方法

fun <F,T> Sequence<F>.mapFirst(block: (F) -> T?): T? =
    fold(AtomicReference<T>()) { ref, from ->
        if (ref.get() != null) return@fold ref
        ref.set(block(from))
        ref
    }.get()

fun main() {
    Files.list(someDir).asSequence().map { it.toFile() }.mapFirst { file ->
        file.useLines { lines ->
            lines.mapFirst { line ->
                if (line == "123") line.toInt() else null
            }
        }
    }?.let { num ->
        println("num is $num") // will print 123 as an Int
    } ?: println("not a single file had a line eq to '123'")
}

但这并没有在比赛中停止(当 block() 返回非空值时)并且会消耗所有文件及其所有行。

最佳答案

一个简单的for循环足以实现 mapFirst :

fun <F,T> Sequence<F>.mapFirst(block: (F) -> T?): T? {
    for (e in this) { 
        block(e)?.let { return it }
    }
    return null
}

如果您需要一个不引入您自己的扩展的解决方案(尽管它没有任何问题),您可以使用 mapNotNull + firstOrNull组合:
files.asSequence()
    .mapNotNull { /* read the first line and return not null if it's ok */ }
    .firstOrNull()

关于kotlin - Kotlin 中序列的查找和转换,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/54601063/

相关文章:

functional-programming - 是否可以在没有突变的情况下在 Scheme 中创建循环数据结构?

scala - 如何加入两个数组是scala

android - 在 Android api 级别 27 中将 getContext() 覆盖为非空是个坏主意?

java - 如何将 Java 赋值表达式转换为 Kotlin

kotlin - 将 "Callable<T>"Java 方法转换为 Kotlin

haskell - 是否有带有显式子类型的 ADT 名称?

Javascript 对象样式模块到函数式编程

java - Kotlin:为什么 !!运算符在为 jvm 编译时生成空检查?

kotlin - Kotlin 中的延续是否可用?有可用的例子吗?

Haskell - 由于我不明白的原因,非穷举模式