Aswath
Aswath

Reputation: 986

Kotlin Filter list with multiple conditions - Return Either error or valid items

I'm having a kotlin list of objects List<A>

data class A (
 type : enum (TypeA, TypeB, TypeC)
)

I want to filter the list to find valid items and return Either error or valid items

  1. If type is TypeA return error
  2. If type is TypeB do some more check and if failed return error

Below is one way to achieve it

val a: List<A> = listOf(...)

fun validate(
      list: List<A>,
  ): Either<Error, List<A>> {
    val filteredList = ArrayList<A>()

    list.forEach { l ->
      when (l.type) {
        TypeA -> {
          if (some condition)
              return Either.Left(ErrorA)
        }
        TypeB ->
            return Either.Left(ErrorB)
        TypeC ->
            return Either.Left(ErrorC)
        else -> {
          filteredList.add(l)
        }
      }
    }
    return Either.Right(filteredList)
  }

Looking for a kotlin way of achieving with expressions

Upvotes: 2

Views: 3568

Answers (1)

Ivo
Ivo

Reputation: 23164

I'm not sure if you are maybe able to link the error to the enum. But in that case you might be able to add this function to the enum and do this for example.

class ErrorA : Error()
class ErrorB : Error()
class ErrorC : Error()
val condition = true

data class A (val type : AType)

enum class AType {TypeA, TypeB, TypeC, TypeD;
    fun getError() : Error? =
        when(this) {
            TypeA -> if (condition) ErrorA() else null
            TypeB -> ErrorB()
            TypeC -> ErrorC()
            else -> null
        }
}


fun validate(list: List<A>): Either<Error, List<A>> = 
    list.firstOrNull { it.type.getError() != null }?.type?.getError()?.left() ?:
    list.filter { it.type.getError() == null }.right()

I'm not sure if it can be made more efficient in a way because with this solution the list gets iterated twice but at least it's a single expression solution

Upvotes: 1

Related Questions