Как улучшить эту функцию? - PullRequest
0 голосов
/ 06 июня 2018

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

case class B(bx: Int)
case class A(ax: Int, bs: Seq[B])

Я пишу функцию A => Seq[(Int, Option[Int])] следующим образом:

def foo(a: A): Seq[(Int, Option[Int])] = 
  if (a.bs.isEmpty) Seq((a.ax, None)) else a.bs.map(b => (a.ax, Some(b.bx)))

Кажется, работает, но я нене нравится ветвление.Как бы вы улучшили foo?

Ответы [ 2 ]

0 голосов
/ 06 июня 2018

Другой вариант - добавить вспомогательную функцию, которая принимает Seq[T] и возвращает Seq[Option[T]], где вывод никогда не пуст - если вход пуст, выход будет иметь один Noneэлемент в его результате:

def foo(a: A): Seq[(Int, Option[Int])] = toOptions(a.bs.map(_.bx)).map((a.ax, _))

// always returns a non-empty list - with None as the only value for empty input
def toOptions[T](s: Seq[T]): Seq[Option[T]] = s.headOption +: s.drop(1).map(Some(_))

Преимущества:

  • Этот действительно не имеет разветвления (включая getOrElse, который является разновидностью разветвления, хотя иболее элегантный)
  • Нет повторения построения кортежа (a.ax вызывается один раз)
  • Хорошее разделение задач (создание никогда не пустого списка и сопоставление с A и Bs)
0 голосов
/ 06 июня 2018

Используйте Option сопутствующий объект для создания.

def foo(a: A): Seq[(Int, Option[Int])] = 
  Option(a.bs).filterNot(_.isEmpty)
              .map(list => list.map(b => (a.ax, Some(b.bx))))
              .getOrElse(Seq((a.ax, None)))
Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...