如何使用scala case类作为函数参数来指定要使用的不同字段?
我有一些重复的代码,因为必须在一个案例类中的3个不同字段上进行分组,然后用这些字段填充一个新的案例类。因为它们共享一个公共模式,所以我应该可以执行一个函数,该函数可以接受3个不同字段的输入,并相应地进行填充。然而,我并不完全确定如何做到这一点 模式:如何使用scala case类作为函数参数来指定要使用的不同字段?,scala,case-class,Scala,Case Class,我有一些重复的代码,因为必须在一个案例类中的3个不同字段上进行分组,然后用这些字段填充一个新的案例类。因为它们共享一个公共模式,所以我应该可以执行一个函数,该函数可以接受3个不同字段的输入,并相应地进行填充。然而,我并不完全确定如何做到这一点 模式: case class Transaction( senderBank: Bank, receiverBank: Bank, intermediaryBank: Bank) case class Bank( name: String
case class Transaction(
senderBank: Bank,
receiverBank: Bank,
intermediaryBank: Bank)
case class Bank(
name: String,
country: Option[String],
countryCode: Option[String])
case class GroupedBank(
name: String,
country: Option[String],
countryCode: Option[String],
bankType: String)
我尝试执行的当前函数:
def groupedBank(transactionSeq: Seq[Transaction], bankName: Bank, bankTypeString: String): Iterable[Seq[GroupedBank]] = {
transactionSeq.groupBy(_ => bankName.name).map {
case (key, transactionSeq) =>
val bankGroupedSeq = transactionSeq.map(_ => {
GroupedBank(
name = bankName.name,
country = bankName.country,
countryCode = bankName.countryCode,
bankType = bankTypeString)
})
bankGroupedSeq
}
}
我需要对
SenderBank
、receiverBank
和intermediaryBank
进行分组。但是,我不确定如何在函数参数bankName
中正确引用它们。因此,对于SenderBank
,我希望执行类似于Transaction.SenderBank
的操作,这将指向SenderBank
的名称、国家等正确字段。对于receiverBank
,它应该是类似的,因此交易。receiverBank
,然后它引用了receiverBank
的正确字段,依此类推。对于intermediaryBank
同样的逻辑。因此,我的问题是,我如何才能完成这样的事情,或者是否有其他更合适的方式 您可以传递一个函数,从交易中提取具有正确类型的银行:
def groupedBank(
transactionSeq: Seq[Transaction],
getBank: Transaction => Bank,
bankTypeString: String
): Iterable[Seq[GroupedBank]] = {
transactionSeq.groupBy(getBank(_).name).map {
case (key, transactionSeq) =>
transactionSeq.map { transaction =>
val bank = getBank(transaction)
GroupedBank(
name = bank.name,
country = bank.country,
countryCode = bank.countryCode,
bankType = bankTypeString)
}
}
}
然后这样称呼它:
groupedBank(transactionSeq, _.senderBank, "sender")
将银行类型概念抽象为一个单独的特征也是一个好主意:
sealed trait BankGroup {
def name: String
def getBank(transaction: Transaction): Bank
def groupBanks(transactionSeq: Seq[Transaction]): Iterable[Seq[GroupedBank]] = {
transactionSeq.groupBy(getBank(_).name).map {
case (key, transactionSeq) =>
transactionSeq.map { transaction =>
val bank = getBank(transaction)
GroupedBank(
name = bank.name,
country = bank.country,
countryCode = bank.countryCode,
bankType = name)
}
}
}
}
object BankGroup {
object Sender extends BankGroup {
def name: String = "sender"
def getBank(transaction: Transaction): Bank = transaction.senderBank
}
object Receiver extends BankGroup {
def name: String = "receiver"
def getBank(transaction: Transaction): Bank = transaction.receiverBank
}
object Intermediary extends BankGroup {
def name: String = "intermediary"
def getBank(transaction: Transaction): Bank = transaction.intermediaryBank
}
val values: Seq[BankGroup] = Seq(Sender, Receiver, Intermediary)
def byName(name: String): BankGroup = values.find(_.name == name)
.getOrElse(sys.error(s"unknown bank type: $name"))
}
你可以用以下方式之一来称呼它:
BankGroup.Sender.groupBanks(transactionSeq)
BankGroup.byName("sender").groupBanks(transactionSeq)
对不起,不清楚你在做什么。您是否想要
transactionSeq.groupBy(\uu.senderBank.name)
,transactionSeq.groupBy(\uu.receiverBank.name)
,transactionSeq.groupBy(\uu.intermediaryBank.name)
?@DmytroMitin,是的。很抱歉,我有点不清楚。@DmytroMitin,但这在函数中是什么样子的?