如果第一个为空,返回第二个字符串

时间:2014-08-19 22:25:41

标签: scala

这是我发现自己写的一个成语。

def chooseName(nameFinder: NameFinder) = {
  if(nameFinder.getReliableName.isEmpty) nameFinder.getReliableName
  else nameFinder.secondBestChoice
}

为了避免在getReliableName()上调用nameFinder两次,我添加了使我的方法看起来不那么优雅的代码。

def chooseName(nameFinder: NameFinder) = {
  val reliableName = nameFinder.getReliableName()
  val secondBestChoice = nameFinder.getSecondBestChoice()
  if(reliableName.isEmpty) reliableName
  else secondBestChoice
}

这感觉很脏,因为我使用vals创建了一个不必要的状态量,除了防止重复的方法调用之外没有任何理由。斯卡拉告诉我,每当我感到肮脏时,几乎总会有更好的方法。

有更优雅的方式来写这个吗?

Here's two Strings, return whichever isn't empty while favoring the first

5 个答案:

答案 0 :(得分:3)

当然,没有必要随时拨打getSecondBestChoice。就个人而言,我发现在改变之后代码没有任何优雅 - 它清楚它的作用,没有可变的状态。其他答案似乎过于复杂,只是为了避免使用val

def chooseName(nameFinder: NameFinder) = {
  val reliableName = nameFinder.getReliableName()

  if(reliableName.isEmpty) reliableName
  else nameFinder.getSecondBestChoice()
}

如果你真的想避免使用val,那么这是另一个变体(如果有两个以上的替代方案,则说得很好)

List(nameFinder.getReliableName(), nameFinder.getSecondBestChoice()).find(_.nonEmpty).get

(或getOrElse(lastResort),如果列表中的所有内容也可能为空)

答案 1 :(得分:2)

这是使用Option的方法。它并不是那么漂亮,但一切都只召唤一次。这假设您希望结果为String,并且不关心第二个字符串是否为空。

Some(nameFinder.getReliableName)
    .filter(_.nonEmpty)
    .getOrElse(nameFinder.secondBestChoice)

答案 2 :(得分:2)

Option(namefinder.getReliableName) // transforms a potential null into None
.filter(_.trim.nonEmpty) // "" is None, but also "   "
.getOrElse(nameFinder.secondBestChoice)

或者更好的是,如果您可以修改getReliableName以返回Option[String]

def chooseName(nameFinder: NameFinder): String =
  namefinder.getReliableName getOrElse nameFinder.secondBestChoice

最后,如果secondBestChoice也可能失败(假设它返回Option[String]):

def chooseName(nameFinder: NameFinder): Option[String] =
  namefinder.getReliableName orElse nameFinder.secondBestChoice

答案 3 :(得分:2)

如果您需要不止一次:

scala> implicit class `nonempty or else`(val s: String) extends AnyVal {
     | def nonEmptyOrElse(other: => String) = if (s.isEmpty) other else s }
defined class nonempty

scala> "abc" nonEmptyOrElse "def"
res2: String = abc

scala> "" nonEmptyOrElse "def"
res3: String = def

答案 4 :(得分:0)

使用以下模式匹配可以提供更整洁的scalish代码,

def chooseName(nameFinder: NameFinder) = {
  nameFinder.getReliableName match {
    case r if r.isEmpty => r
    case _              => nameFinder.secondBestChoice
  }
}