如果这是一个新手问题,我很抱歉,但这正是我对 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)
}
这确实是一个意见问题,但我个人会将
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
)