Отображение, если исключение

У меня есть список String s, представляющий сериализованные данные, которые я хочу map в список объектов. Я использую следующий код:

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

Однако иногда возникает ошибка синтаксического анализа, и поток просто останавливается, я хотел бы восстановить список до момента отказа. Например, если ошибка возникает в элементе 7, я бы хотел, чтобы doOtherStuff получил 6 элементов, которые были успешно обработаны.

Какой самый идиоматический способ сделать это? Я могу отфильтровать список, чтобы увидеть, будет ли синтаксический анализ успешным, но это дорогостоящая операция, выполняемая дважды.

Вы можете рассматривать исключение как null и затем фильтровать нули.

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

Замените WhateverException правильной для типа ошибок, которые вы хотите обработать, другие ошибки все равно могут остановить обработку.

То, что вы ищете, похоже, является комбинацией map и takeWhile . Вы всегда можете сворачивать самостоятельно. Например, из источников mapNotNull и 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 , вы можете сопоставить все исключения, которые вам нужны для null :

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