Стрелка Kotlin преобразовывает Список сбоев в Сбой списка - PullRequest
0 голосов
/ 22 мая 2019

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

List<Try<String>>

в:

Try<List<String>>

Используя kotlin и стрелку функциональной библиотеки (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() })
   }

Ответы [ 2 ]

3 голосов
/ 22 мая 2019

Если мы не заботимся о сохранении исходных исключений, мы можем сделать что-то вроде этого с помощью 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()

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

1 голос
/ 22 мая 2019

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

 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)
            }
        }
    }
...