处理外部匹配以供理解

问题描述 投票:0回答:1

如果这是一个新手问题,我很抱歉,但这正是我对 Scala 的看法。我有这个初始的理解,但我认为在理解中计算matchedAccounts 是令人困惑的。有谁知道在理解之外计算它的理想方法是什么?

val accountViewer: AccountViewer = new AccountViewer {
    def view(
      csReport: JsObject,
      userAccount: JsObject,
      brands: Option[List[Brands.Brand]],
      obOverviews: Option[Vector[OBOverview]] = None,
      providers: Option[Providers] = None
    )(implicit fc: FlowContext): Vector[Account] = {
      def accountAddress(account: JsObject): Option[JsObject] =
        account
          .extract[String]("addressKey")
          .flatMap(ReportUtil.addressByKey(csReport, _))
          .flatMap(_.extract[JsObject]("structured"))

      for {
        account <- ReportUtil.accounts(csReport)
        accountCategory: String <- account.extract[String]("accountCategory")
        supplierName: String <- account.extract[String]("supplierName")
        status <- findStatus(account)
        brand = brands.flatMap(brandMapper.matchSupplier(supplierName, _)("account viewer"))
        formattedAccount = Account(
          accountCategory = accountCategory,
          supplierName = supplierName,
          status = status,
          name = account.extract[String]("name").getOrElse(AccountUtil.formatName(userAccount)),
          accountNumber = account.extract[String]("maskedAccountNumber"),
          address = accountAddress(account),
          overview = overview(account, accountCategory),
          paymentHistory = paymentHistory(account),
          key = account.extract[String]("key").getOrElse(AccountUtil.generateHash(account)),
          contentKey = brand.map(_.id),
          displayName = brand.map(_.name),
          color = brand.flatMap(_.color),
          logo = brand.flatMap(_.logo),
          loanType = account.extract[String]("loanType"),
          obLiveBalance = None,
          balanceHistory = balanceHistory(account, accountCategory),
          obIncentive = None
        )
        matchedAccounts = (obOverviews, providers) match {
          case (Some(overviews), Some(providers)) =>
            obMatchingService.matchAndFilterObAccountsToReportAccounts(overviews, Vector(formattedAccount), providers)
          case _ => Vector(formattedAccount)
        }
        accountWithOb = matchedAccounts.headOption.getOrElse(formattedAccount)
        accountWithBalanceHistoryUpdated = updateAndFilterBalanceHistory(accountWithOb)
      } yield accountWithBalanceHistoryUpdated
    }

尝试过实现这一点,但不确定它是否正确?

val accountViewer: AccountViewer = new AccountViewer {
    def view(
      csReport: JsObject,
      userAccount: JsObject,
      brands: Option[List[Brands.Brand]],
      obOverviews: Option[Vector[OBOverview]] = None,
      providers: Option[Providers] = None
    )(implicit fc: FlowContext): Vector[Account] = {
      def accountAddress(account: JsObject): Option[JsObject] =
        account
          .extract[String]("addressKey")
          .flatMap(ReportUtil.addressByKey(csReport, _))
          .flatMap(_.extract[JsObject]("structured"))

      val formattedAccounts = ReportUtil.accounts(csReport).flatMap { account =>
        for {
          accountCategory: String <- account.extract[String]("accountCategory")
          supplierName: String <- account.extract[String]("supplierName")
          status <- findStatus(account)
          brand = brands.flatMap(brandMapper.matchSupplier(supplierName, _)("account viewer"))
          formattedAccount = Account(
            accountCategory = accountCategory,
            supplierName = supplierName,
            status = status,
            name = account.extract[String]("name").getOrElse(AccountUtil.formatName(userAccount)),
            accountNumber = account.extract[String]("maskedAccountNumber"),
            address = accountAddress(account),
            overview = overview(account, accountCategory),
            paymentHistory = paymentHistory(account),
            key = account.extract[String]("key").getOrElse(AccountUtil.generateHash(account)),
            contentKey = brand.map(_.id),
            displayName = brand.map(_.name),
            color = brand.flatMap(_.color),
            logo = brand.flatMap(_.logo),
            loanType = account.extract[String]("loanType"),
            obLiveBalance = None,
            balanceHistory = balanceHistory(account, accountCategory),
            obIncentive = None
          )
        } yield formattedAccount
      }

      val matchedAccounts = (obOverviews, providers) match {
        case (Some(overviews), Some(providers)) =>
          obMatchingService.matchAndFilterObAccountsToReportAccounts(overviews, formattedAccounts, providers)
        case _ => formattedAccounts
      }
      matchedAccounts.map(updateAndFilterBalanceHistory)

    }
scala for-loop functional-programming pattern-matching
1个回答
0
投票

这确实是一个意见问题,但我个人会将

match
留在
for
中,因为它使数据流更清晰一些。我肯定会将
account <- ReportUtil.accounts(csReport)
保留在
for
中,而不是在第二个版本中将
flatMap
单独保留。

但为了清楚起见,我会将所有作业移至

yield
块中。

for {
    account <- ...
    accountCategory <- ...
    supplierName <- ...
    status <- ...
} yield {
    val brand = ...
    val matchedAccounts = ...
    val accountWithOb = ...

    updateAndFilterBalanceHistory(accountWithOb)
}

如果我要在稍后的

=
操作中使用该值,我只会在
for
中使用
<-

我可能还会向

account
和其他帮助器添加一些扩展方法来简化代码,使逻辑更清晰。 (例如
account.get
而不是
account.extract[String]
account.getOrElse

© www.soinside.com 2019 - 2024. All rights reserved.