4
  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 操作から受け取ったものなので、対処する必要があります。この複雑なタプル/オプション構造からすべての反復子オプションを取得するより良い方法はありますか?

4

1 に答える 1

2

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)
}

ここでは、フォールバック値をカプセル化するために、 getOrElse連続してネストされた各 onを使用しました。Option

パターン マッチング構文 (変数宣言と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 のようなライブラリを使用することを検討してください。これにより、この複雑な型をより簡潔に処理できるようになる可能性があります。それはやり過ぎだと思いますが。

于 2015-05-11T11:23:12.073 に答える