【问题标题】:A better implementation for pattern matching a tree-like option structure模式匹配树状选项结构的更好实现
【发布时间】:2015-07-21 14:13:42
【问题描述】:
  def leadParser(optionTuples: Option[(Option[(Option[(Option[(Option[(
                                Option[Iterable[EmailLead]],
                                Option[Iterable[QuestionLead]])],
                                Option[Iterable[LocalMarketQuestionLead]])],
                                Option[Iterable[OfferLead]])],
                                Option[Iterable[Bid]])],
                                Option[Iterable[CreditApplicationLeadWithEbayId]])]) = {
    optionTuples match{
      case None => (None, None, None, None, None, None)
      case Some(c) =>
        val creditApplictaionIteratorOption = c._2
        c._1 match {
          case None => (None, None, None, None, None, creditApplictaionIteratorOption)
          case Some(b) =>
            val bidIteratorOption = b._2
            b._1 match {
              case None => (None, None, None, None, bidIteratorOption, creditApplictaionIteratorOption)
              case Some(o) =>
                val offerIteratorOption = o._2
                o._1 match {
                  case None => (None, None, None, offerIteratorOption, bidIteratorOption, creditApplictaionIteratorOption)
                  case Some(l) =>
                    val localMarketQuestionIteratorOption = l._2
                    l._1 match {
                      case None => (None, None, localMarketQuestionIteratorOption, offerIteratorOption, bidIteratorOption, creditApplictaionIteratorOption)
                      case Some(q) =>
                        val questionIteratorOption = q._2
                        val emailIteratorOption = q._1
                        (emailIteratorOption, questionIteratorOption, localMarketQuestionIteratorOption, offerIteratorOption, bidIteratorOption, creditApplictaionIteratorOption)
                        }
                    }
                }
            }
        }
}

我知道输入 Option[... 看起来很疯狂,但这是我从 Spark 操作中收到的,所以我必须处理它。有没有更好的方法从这个复杂的元组/选项结构中获取所有迭代器选项?

【问题讨论】:

  • 我正在考虑一个更容易阅读的递归函数。你试过写递归函数了吗?
  • 每次迭代输入类型都会改变。我想过使用带有函数的flatMap,但它不起作用。 @B.Kemmer 在该函数中,我实际上尝试将 inputType 定义为 Option[(Option[Iterator], Option[_])] 但它不起作用。

标签: scala pattern-matching tuples scala-option


【解决方案1】:

您可以使用模式匹配来声明变量,而不仅仅是在case 语句中。这解锁了几个更具可读性的非嵌套可能性。例如:

def leadParser(optionTuples: Option[(Option[(Option[(Option[(Option[(Option[Iterable[EmailLead]],Option[Iterable[QuestionLead]])],Option[Iterable[LocalMarketQuestionLead]])],Option[Iterable[OfferLead]])],Option[Iterable[Bid]])],Option[Iterable[CreditApplicationLeadWithEbayId]])]) = {
    val (creditRest, credit) = optionTuples.getOrElse(None -> None)
    val (bidRest, bid) = creditRest.getOrElse(None -> None)
    val (offerRest, offer) = bidRest.getOrElse(None -> None)
    val (localRest, local) = offerRest.getOrElse(None -> None)
    val (email, question) = localRest.getOrElse(None -> None)
    (credit, bid, offer, local, email, question)
}

在这里,我们在每个连续嵌套的Option 上使用了getOrElse,以封装后备值。

模式匹配语法(在变量声明和match 子句中)可以嵌套以说明内部结构。这给了你另一种可能性:

def leadParser(optionTuples: Option[(Option[(Option[(Option[(Option[(Option[Iterable[EmailLead]],Option[Iterable[QuestionLead]])],Option[Iterable[LocalMarketQuestionLead]])],Option[Iterable[OfferLead]])],Option[Iterable[Bid]])],Option[Iterable[CreditApplicationLeadWithEbayId]])]) = {
    optionTuples match {
        case Some((Some((Some((Some((Some((a, b)), c)), d)), e)), f)) => (a, b, c, d, e, f)
        case Some((Some((Some((Some((None, c)), d)), e)), f)) => (None, None, c, d, e, f)
        case Some((Some((Some((None, d)), e)), f)) => (None, None, None, d, e, f)
        case Some((Some((None, e)), f)) => (None, None, None, None, e, f)
        case Some((None, f)) => (None, None, None, None, None, f)
        case None => (None, None, None, None, None, None)
    }
}

这里我们使用几个嵌套模式匹配来捕获复杂值的内部结构。

这里的其他自然选择是某种防止嵌套的for 理解,或者是扁平化这种类型的可选元组的通用递归函数。最后,如果这太麻烦,您可以考虑使用像 Shapeless 这样的库,可以让您更简洁地使用这种复杂类型。不过,我认为那将是矫枉过正。

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2020-10-14
    • 2021-05-04
    • 1970-01-01
    • 1970-01-01
    • 2019-09-10
    • 1970-01-01
    相关资源
    最近更新 更多