Стрелка Kotlin преобразует список сбоев в сбой списка

Как я могу преобразовать следующее:

List<Try<String>>

к:

Try<List<String>>

Использование kotlin и функциональной библиотеки arrow (0.8.2). Я хотел бы обернуть его в пользовательское исключение. Неважно, какой из «String» потерпел неудачу.

Обновлять:

Поскольку приведенных ниже ответов будет достаточно, но мне очень трудно читать. Итак, я реализовал следующее:

Создайте следующую функцию:

    fun getFailedStrings(result: List<Try<String>>): List<Failure> {
return result.fold(
    initial = listOf(),
    operation = { accumulator, nextUpdate ->
        nextUpdate.fold(
            ifSuccess = { accumulator },
            ifFailure = { accumulator + Failure(it) }
        )
    })

}

Затем используйте результат функции:

  return if (failedStrings.isNotEmpty()) {
      failedStrings.first() // or whatever fits your usecase
  } else {
     // strings is the initial result of List<Try<String>>
      Success(strings.mapNotNull { it.orNull() })
   }

Ваш Try<List<String>> может содержать несколько строк, но только одно исключение. Поэтому вам нужно сначала решить, как вы будете комбинировать исключения. Если несколько ваших Try являются неудачными, какое исключение вы бы хотели? Первый? Последний? Новый с причиной, установленной на первый или последний?

Joffrey 22.05.2019 16:55

Хороший вопрос. Новый (кастомный). Неважно, какой из них потерпел неудачу.

ielkhalloufi 22.05.2019 17:23
3 метода стилизации элементов HTML
3 метода стилизации элементов HTML
Когда дело доходит до применения какого-либо стиля к нашему HTML, существует три подхода: встроенный, внутренний и внешний. Предпочтительным обычно...
Формы c голосовым вводом в React с помощью Speechly
Формы c голосовым вводом в React с помощью Speechly
Пытались ли вы когда-нибудь заполнить веб-форму в области электронной коммерции, которая требует много кликов и выбора? Вас попросят заполнить дату,...
Стилизация и валидация html-формы без использования JavaScript (только HTML/CSS)
Стилизация и валидация html-формы без использования JavaScript (только HTML/CSS)
Будучи разработчиком веб-приложений, легко впасть в заблуждение, считая, что приложение без JavaScript не имеет права на жизнь. Нам становится удобно...
Flatpickr: простой модуль календаря для вашего приложения на React
Flatpickr: простой модуль календаря для вашего приложения на React
Если вы ищете пакет для быстрой интеграции календаря с выбором даты в ваше приложения, то библиотека Flatpickr отлично справится с этой задачей....
В чем разница между Promise и Observable?
В чем разница между Promise и Observable?
Разберитесь в этом вопросе, и вы значительно повысите уровень своей компетенции.
Что такое cURL в PHP? Встроенные функции и пример GET запроса
Что такое cURL в PHP? Встроенные функции и пример GET запроса
Клиент для URL-адресов, cURL, позволяет взаимодействовать с множеством различных серверов по множеству различных протоколов с синтаксисом URL.
0
2
1 020
2
Перейти к ответу Данный вопрос помечен как решенный

Ответы 2

это похоже на работу:

 fun convert(input: List<Try<String>>): Try<List<String>> =
    input.fold(Try.just(emptyList())) { acc, i ->
        acc.flatMap { list ->
            i.flatMap {
                Try.just(list + it)
            }
        }
    }

Было бы здорово, если бы использование библиотеки стрелок могло обеспечить большую читабельность

ielkhalloufi 22.05.2019 18:29
Ответ принят как подходящий

Если мы не заботимся о сохранении исходных исключений, мы могли бы сделать что-то подобное с traverse:

val traversedTries = tries.traverse(Try.applicative(), ::identity)

Это вернет экземпляр типа Try<ListK<String>> либо со всеми строками, либо с первым найденным исключением.

ListK является продолжением List, но мы можем дополнительно преобразовать его, добавив .map { it as List<String> } в конце, если нам нужно, чтобы это было Try<List<String>>

В качестве альтернативы, если мы хотим разделить успехи и неудачи, мы можем создать следующую функцию:

fun <A> List<Try<A>>.splitSuccessFailure() : Tuple2<List<A>, List<Throwable>> =
  fold(emptyList<A>() toT emptyList<Throwable>()) { (successes, failures), it -> 
    it.fold({ successes toT (failures + it) }, { (successes + it) toT failures })  
  }

Затем, когда мы хотим использовать его, мы можем сделать следующее:

val (successes, failures) = invalidTries.splitSuccessFailure()

Предоставление нам двух списков со значениями успехов и неудач соответственно.

Кажется, я не могу найти метод расширения .traverse для списка Kotlin.

ielkhalloufi 22.05.2019 18:26

Вам нужен импорт: import arrow.data.extensions.list.traverse.* и вам также нужно добавить зависимость к arrow-extras-extensions

pablisco 22.05.2019 18:30

Другие вопросы по теме