将案例类字段与Scala中另一个案例类的子字段进行比较

jac*_*iao 5 functional-programming scala

我有以下3个案例类:

case class Profile(name: String,
                   age: Int,
                   bankInfoData: BankInfoData,
                   userUpdatedFields: Option[UserUpdatedFields])

case class BankInfoData(accountNumber: Int,
                        bankAddress: String,
                        bankNumber: Int,
                        contactPerson: String,
                        phoneNumber: Int,
                        accountType: AccountType)

case class UserUpdatedFields(contactPerson: String,
                             phoneNumber: Int,
                             accountType: AccountType)
Run Code Online (Sandbox Code Playgroud)

这只是枚举,但是我还是添加了:

sealed trait AccountType extends EnumEntry

object AccountType extends Enum[AccountType] {
  val values: IndexedSeq[AccountType] = findValues

  case object Personal extends AccountType

  case object Business extends AccountType

}
Run Code Online (Sandbox Code Playgroud)

我的任务是-我需要编写一个funcc Profile,并将UserUpdatedFields(所有字段)与BankInfoData中的某些字段进行比较...此功能是查找要更新的字段。

所以我写了这个函数:

def findDiff(profile: Profile): Seq[String] = {
  var listOfFieldsThatChanged: List[String] = List.empty
  if (profile.bankInfoData.contactPerson != profile.userUpdatedFields.get.contactPerson){
    listOfFieldsThatChanged = listOfFieldsThatChanged :+ "contactPerson"
  }
  if (profile.bankInfoData.phoneNumber != profile.userUpdatedFields.get.phoneNumber) {
    listOfFieldsThatChanged = listOfFieldsThatChanged :+ "phoneNumber"
  }
  if (profile.bankInfoData.accountType != profile.userUpdatedFields.get.accountType) {
    listOfFieldsThatChanged = listOfFieldsThatChanged :+ "accountType"
  }
  listOfFieldsThatChanged
}

val profile =
  Profile(
    "nir",
    34,
    BankInfoData(1, "somewhere", 2, "john", 123, AccountType.Personal),
    Some(UserUpdatedFields("lee", 321, AccountType.Personal))
  )

findDiff(profile)
Run Code Online (Sandbox Code Playgroud)

它可行,但是想要更干净的..任何建议吗?

Mar*_*lic 3

每个案例类都扩展了Product接口,因此我们可以使用它将案例类转换为(字段,值)元素集。然后我们就可以利用集合运算来求差异。例如,

  def findDiff(profile: Profile): Seq[String] = {
    val userUpdatedFields = profile.userUpdatedFields.get
    val bankInfoData = profile.bankInfoData

    val updatedFieldsMap = userUpdatedFields.productElementNames.zip(userUpdatedFields.productIterator).toMap
    val bankInfoDataMap = bankInfoData.productElementNames.zip(bankInfoData.productIterator).toMap
    val bankInfoDataSubsetMap = bankInfoDataMap.view.filterKeys(userUpdatedFieldsMap.keys.toList.contains)
    (bankInfoDataSubsetMap.toSet diff updatedFieldsMap.toSet).toList.map { case (field, value) => field }
  }
Run Code Online (Sandbox Code Playgroud)

现在findDiff(profile)应该输出List(phoneNumber, contactPerson). 请注意,我们使用Scala 2.13 中的ProductElementNames来获取文件名,然后将其与相应的值一起压缩

userUpdatedFields.productElementNames.zip(userUpdatedFields.productIterator)
Run Code Online (Sandbox Code Playgroud)

我们还依赖filterKeysdiff