Scala Группа списка проверки библиотеки Cat по коду ошибки - PullRequest
2 голосов
/ 27 мая 2020

Я новичок в Scala и функциональном программировании. Я провел одну проверку с использованием библиотеки Scala cat. Но я не могу сгруппировать недопустимые элементы по коду ошибки.

case class Err(code: ErrorCode, elementName: String)

Это результат недопустимых элементов.

List(Invalid(NonEmptyList(Err(missingElement,Des), Err(InvalidElement,order), Err(InvalidElement,name), Err(InvalidElement,source))))

то, что я хочу, выглядит примерно так

missingElement->List(Des)
InvalidElement->List(order,name,source)

Есть ли для этого какие-то функции в самой библиотеке cat? Или есть какое-то обходное решение?

1 Ответ

3 голосов
/ 27 мая 2020

Предположим, ваша полная структура выглядит примерно так:

sealed trait ErrorCode
object ErrorCode {
  case object MissingElement extends ErrorCode
  case object InvalidElement extends ErrorCode
}

final case class Err(code: ErrorCode, elementName: String)

И у нас есть ValidatedNel[Err, ?]:

val res: ValidatedNel[Err, String] =
  Invalid(
    NonEmptyList(
      Err(ErrorCode.MissingElement, "Des"),
      List(
        Err(ErrorCode.InvalidElement, "order"),
        Err(ErrorCode.InvalidElement, "name"),
        Err(ErrorCode.InvalidElement, "source")
      )
    )
  )

Тогда что вам нужно сделать, чтобы сгруппировать в списке будет использоваться groupBy на стороне ошибки, используя leftMap:

val groupedErrs: Validated[Map[ErrorCode, List[String]], String] =
  res.leftMap(
    _.toList
      .groupBy(_.code)
      .map { case (code, errs) => code -> errs.map(_.elementName) }
  )

Результат:

Invalid(Map(InvalidElement -> List(order, name, source), MissingElement -> List(Des)))

Если все это находится внутри списка проверок, List[ValidatedNel[Err, ?]], то нам просто нужна дополнительная операция map для перебора списка:

val groupedErrs: List[Validated[Map[ErrorCode, List[String]], String]] = 
  res.map(
    _.leftMap(
      _.toList
        .groupBy(_.code)
        .map { case (code, errs) => code -> errs.map(_.elementName) }
    )
  )

Результат:

List(Invalid(Map(InvalidElement -> List(order, name, source), MissingElement -> List(Des))))
...