我有一个String
列表,表示我想要map
到对象列表的序列化数据。我使用以下代码:
strings.map { gson.fromJson(it, Model::class.java) }
// .doOtherStuff
但是,有时会出现解析错误并且流停止,我希望能够恢复列表直到失败。例如,如果错误发生在第7项,我希望doOtherStuff
获得已成功处理的6个项目。
最常用的方法是什么?我可以过滤列表以查看解析是否会成功,但是执行两次这是一项昂贵的操作。
答案 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)
您正在寻找的内容似乎是map
和takeWhile
的组合。你可以随时自己动手。例如以下内容改编自mapNotNull
和takeWhile
的来源:
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 Minard的example一样,您可以将所需的任何异常映射到null
}:
strings.mapWhileNotNull {
try {
gson.fromJson(it, Model::class.java)
} catch (e: JsonSyntaxException) {
null
}
}
// .doOtherStuff