映射除非异常

时间:2016-11-09 23:50:44

标签: kotlin

我有一个String列表,表示我想要map到对象列表的序列化数据。我使用以下代码:

strings.map { gson.fromJson(it, Model::class.java) }
// .doOtherStuff

但是,有时会出现解析错误并且流停止,我希望能够恢复列表直到失败。例如,如果错误发生在第7项,我希望doOtherStuff获得已成功处理的6个项目。

最常用的方法是什么?我可以过滤列表以查看解析是否会成功,但是执行两次这是一项昂贵的操作。

2 个答案:

答案 0 :(得分:9)

您可以将异常视为null,然后过滤空值。

val models = modelsInJson.mapNotNull { json ->
    try {
        gson.fromJson(json, Model::class.java) 
    } catch (ex: WhateverException) {
        // TODO: logging here?
        null
    }
}

WhateverException替换为您要处理的错误类型的正确值,其他错误仍然可以停止处理。

答案 1 :(得分:3)

您正在寻找的内容似乎是maptakeWhile的组合。你可以随时自己动手。例如以下内容改编自mapNotNulltakeWhile的来源:

inline fun <T, R : Any> Iterable<T>.mapWhileNotNull(transform: (T) -> R?): List<R> {
    return mapWhileNotNullTo(ArrayList<R>(), transform)
}

inline fun <T, R : Any, C : MutableCollection<in R>> Iterable<T>.mapWhileNotNullTo(destination: C, transform: (T) -> R?): C {
    for (element in this) {
        val transformed = transform(element)
        if (transformed == null) {
            break
        } else {
            destination.add(transformed)
        }
    }
    return destination
}

现在,您可以将可迭代映射到导致null的转换调用,并且与Jayson Minardexample一样,您可以将所需的任何异常映射到null }:

strings.mapWhileNotNull {
    try {
        gson.fromJson(it, Model::class.java)
    } catch (e: JsonSyntaxException) {
        null
    }
}
// .doOtherStuff