Полиморфная функция Scala для фильтрации входного списка либо


В поисках более элегантного решения

У меня есть этот фрагмент кода, я просто использую его в тестовых случаях, когда нет необходимости делать какую-либо обработку ошибок. Что он делает, так это:

  • Возьмите входной список строк
  • проанализируйте их с помощью DSJSonmapper.метод parseDSResult
  • фильтрует их и извлекает правое значение из каждого (левый-исключение)

Код выглядит следующим образом:

  def parseDs(ins: List[String]) = {
    def filterResults[U, T](in: List[Either[U, T]]): List[T] = {
      in.filter(y => y.isRight).map(z => z.right.get)
    }
    filterResults(ins.map(x => DSJsonMapper.parseDSResult(x)))
  }

Итак, я не сделал слишком много полиморфных функций, но это работает. Однако я чувствую, что это немного некрасиво. У кого - нибудь есть лучшее предложение, как сделать то же самое?

Я знаю, что это будет сводиться к случаю личных предпочтений. Но предложения приветствуются.

2 7

2 ответа:

collect создан именно для такого рода ситуаций:

def filterMe[U,T](in: List[Either[U,T]]): List[T] = in.collect{
  case Right(r) => r
}

На самом деле, это настолько хорошо, что вы можете пропустить def и просто

ins.map(DSJsonMapper.parseDsResult).collect{ case Right(r) => r }

Ответ Рекса, возможно, немного яснее, но вот немного более короткая альтернатива, которая анализирует и "фильтрует" в один шаг:

ins.flatMap(DSJsonMapper.parseDSResult(_).right.toOption)

Здесь мы беремправую проекцию каждого результата разбора и превращаем его в Option (который будет None, Если разбор не удался и Some(whatever) в противном случае). Поскольку мы используем flatMap, Nones не появляются в результате, и значения извлекаются из Somes.