Scala - недоступный код при сопоставлении с шаблоном логических значений и значения по умолчанию - PullRequest
0 голосов
/ 25 февраля 2019

У меня есть Map[String, Boolean] с различными данными метрик и отдельный Seq[String], содержащий metricKeys.

Проблема в том, что Карта может содержать не все metricKeys, но мне также необходимо хранить информацию о несуществующих значениях.Я пытался решить эту проблему с помощью .getOrElse.Я ожидал, что результирующее List[String] со значениями метрики будет содержать «Y» для true, «N» для false и «» для null значений.

Однако я получаю предупреждение: unreachable code case _ => StringUtils.EMPTY.Какой будет правильный способ получить значения по умолчанию, также сопоставленные правильно?

def parseMetrics(metric: Metric): List[String] = {
    import scala.collection.JavaConverters._
    val metricKeys: Seq[String] = getMetricKeys
    val matricsData = metric.transactionMap.asScala

metricKeys.map(key => key -> matricsData.getOrElse(key, null))
      .toMap.values.map(Predef.Boolean2boolean).collect  {
      case true => "Y"
      case false => "N"
      case _ => StringUtils.EMPTY
    }.toList
}

Ответы [ 2 ]

0 голосов
/ 25 февраля 2019

Я предполагаю, что это продолжение этого вопроса , а matricsData имеет тип, подобный Map[String, java.lang.Boolean]?

Проблема в том, что преобразование Predef.Boolean2booleanиз упакованных Java-логических выражений в Scala Booleans возвращает false, когда его аргумент равен null, поэтому, если вы хотите различать значения java.lang.Boolean true, false и null, вам нужно будет сделать это перед преобразованием(независимо от того, является ли это преобразование явным, как оно есть здесь).

Однако есть гораздо лучшие способы приблизиться к этому, например, следующее:

metricKeys.map { key =>
  matricsData.get(key) match {
    case Some(value) => if (value) "Y" else "N"
    case None        => StringUtils.EMPTY
  }
}

Или использовать foldна Option вместо сопоставления с шаблоном:

metricKeys.map { key =>
  matricsData.get(key).fold(StringUtils.EMPTY) { value =>
    if (value) "Y" else "N"
  }
}

Или сначала преобразуйте значения карты, а затем найдите все ваши ключи:

val asYN: Map[String, String] = matricsData.mapValues { value =>
  if (value) "Y" else "N"
}

metricKeys.map(key => asYN.getOrElse(key, StringUtils.EMPTY))

Какой подход вы выберете - дело вкуса, но любой из них лучше, чем использование булевых Java-выражений в штучной упаковке для моделирования каких-либо трехсторонних данных типа «правда или ложь, или отсутствие».

0 голосов
/ 25 февраля 2019

Просто используйте map.get, который вернет Option [Boolean], а затем регистр для Some (true), Some (false) и None

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...