Empresas
Empregos
  • Sobre nós
  • Soluções
    • Publicação de vagas
      Publique sua vaga e receba candidatos qualificados em 48h.
    • Avaliações de candidatos
      Mais de 500 testes técnicos e psicológicos, mais anti-fraude.
    • Headhunting
      Busca executiva personalizada do início ao fim.
    • Folha de Pagamento + EOR
      Dispersão de folha e EOR em mais de 15 países da LATAM.
  • Preços
  • Empregos

0

466
Visualizações
Kotlin: ¿cómo mapear correctamente el resultado usando cualquiera?

Estoy tratando de leer una lista de objetos de la base de datos y asignarla a otro tipo de lista.

 // Returns either a Failure or the expected result suspend fun getCountries(): Either<Failure, List<CountryItem>> { // Get the result from the database val result = countryLocalDataSource.getCountries() // Left means Failure if (result.isLeft) { // Retrieve the error from the database lateinit var error: Failure result.either({ error = it }, {}) // Return the result return Either.Left(error) } // The database returns a List of Country objects, we need to map it to another object (CountryItem) val countryItems: MutableList<CountryItem> = mutableListOf() // Iterate the Country List and construct a new List of CountryItems result.map { countries -> { countries.forEach { // Assign some values from an Enum (localized string resources) val countryEnumValue = Countries.fromId(it.id) countryEnumValue?.let { countryIt -> val countryStringNameRes = countryIt.nameStringRes; // Create the new CountryItem object (@StringRes value: Int, isSelected: Bool) countryItems.add(CountryItem(countryStringNameRes, false)) } } } } // Because this is a success, return as Right with the newly created List of CountryItems return Either.Right(countryItems) }

En aras de la legibilidad, no incluí todo el Repository o las clases DAO y dejé comentarios en el fragmento de código anterior.

En pocas palabras : estoy usando Coroutines de Kotlin para acceder a la base de datos en un hilo separado y estoy manejando la respuesta en el UI Thread de usuario. Usar la clase Cualquiera para devolver dos resultados diferentes (fracaso o éxito).

El código anterior funciona, sin embargo, es demasiado feo. ¿Es este el enfoque correcto para entregar el resultado?

Lo que estoy tratando de hacer es refactorizar el código anterior.

Todo el problema es causado por los dos tipos de objetos diferentes. La Database Data Source API la base de datos devuelve un Either<Failure, List<Country>> , mientras que se espera que la función devuelva un Either<Failure, List<CountryItem>> .

No puedo entregar un List<CountryItem> directamente desde la Database Data Source API de la base de datos, porque Android Studio no me permite compilar el proyecto (entidades que implementan interfaces, error de compilación, etc.). Lo que estoy tratando de lograr es mapear el resultado de Either de una manera más agradable.

over 4 years ago · Santiago Trujillo
3 Respostas
Responde à pergunta

0

Intenta usar el resultado de Kotlin

Así que en tu caso puedes escribir algo como:

 return result.mapCatching { list: List<Country> -> /*return here List<CountryItem>>*/ }

Y para comprobar el resultado de la llamada:

 result.fold( onSuccess = {...}, onFailure = {...} )

Para invocar un constructor debe llamar a Result.success(T) o Result.failure(Throwable)

Desafortunadamente, también deberá suprimir las advertencias de uso como tipo de devolución Cómo

over 4 years ago · Santiago Trujillo Relatório

0

Puede simplificar comprobando el tipo de Either y accediendo directamente al valor. En tu caso:

acceda a Left a través result.a -> Failure

acceda a Right a través result.b -> List<Country>

ex:

 when (result) { is Either.Left -> { val failure: Failure = result.b ... } is Either.Right -> { val countries: List<Country> = result.b ... } }

Una alternativa es usar la función either() (normalmente esto se llama fold() ):

 result.either( { /** called when Left; it == Failure */ }, { /** called when Right; it == List<Country> */ } )
over 4 years ago · Santiago Trujillo Relatório

0

Suponga que su clase de Country se define de la siguiente manera:

 data class Country(val name: String) {}

y su clase CountryItem se define de la siguiente manera:

 data class CountryItem(private val name: String, private val population: Int) {}

y su clase CountryLocalDataSource con un método getCountries() como este:

 class DataSource { suspend fun getCountries(): Either<Exception, List<Country>> { return Either.Right(listOf(Country("USA"), Country("France"))) //return Either.Left(Exception("Error!!!")) } }

entonces la respuesta a tu pregunta seria:

 suspend fun getCountryItems(): Either<Exception, List<CountryItem>> { when (val countriesOrFail = DataSource().getCountries()) { is Either.Left -> { return Either.Left(countriesOrFail.a) } is Either.Right -> { val countryItems = countriesOrFail.b.map { CountryItem(it.name, 1000) } return Either.Right(countryItems) } } }

Para llamar a su getCountryItems() , aquí hay un ejemplo:

 suspend fun main() { when (val countriesOrFail = getCountryItems()) { is Either.Left -> { println(countriesOrFail.a.message) } is Either.Right -> { println(countriesOrFail.b) } } }

Aquí está el código de muestra en el patio de recreo: https://pl.kotl.in/iiSrkv3QJ

Una nota sobre su función de mapa:

Supongo que en realidad no necesita que el resultado sea MutableList<CountryItem> pero tuvo que definirlo porque desea agregar un elemento a medida que itera a través de la lista de entrada List<Country> .

Quizás el siguiente sea el caso: si tiene una List<Country> con 2 elementos como en el ejemplo, y desea mapear para que el resultado se convierta en una List<CountryItem> con también 2 elementos correspondientes, entonces no necesita para llamar a forEach dentro de un fun que se pasa al map de funciones de orden superior. Pero esta puede ser una pregunta completamente nueva.

over 4 years ago · Santiago Trujillo Relatório
Responde à pergunta
Encontrar trabalhos remotos

Descubra a nova forma de encontrar um emprego!

melhores empregos
Principais categorias de trabalho
Empresas
Postar vaga Preços Comercial
Jurídico
Termos e Condições Política de privacidade
© 2026 PeakU Inc. All Rights Reserved.
Andres GPT
Recomende algumas ofertas para mim
Preciso de ajuda