如何在scala中将每个元素与列表中的其他元素进行深入比较(可选文件)
我有代表report的case类,report有费用如何在scala中将每个元素与列表中的其他元素进行深入比较(可选文件),scala,Scala,我有代表report的case类,report有费用 case class FakeExpense(amount: Option[Double], country: Option[String], currency: Option[String]) case class FakeReport(id: Int, expenses: List[FakeExpense]) 如果报告有效与否,我想返回true/false,如果有两个开支字段完全相同,则返回true/false是无效的……使用scala
case class FakeExpense(amount: Option[Double], country: Option[String], currency: Option[String])
case class FakeReport(id: Int, expenses: List[FakeExpense])
如果报告有效与否,我想返回true/false,如果有两个开支字段完全相同,则返回true/false是无效的……使用scala做这样的事情的正确方法是什么
有效报告:
val report = FakeReport(1, List(FakeExpense(Some(150), Some("US"), Some("USD")),FakeExpense(Some(85), Some("DE"), Some("EUR"))))
val report = FakeReport(2, List(FakeExpense(Some(150), Some("US"), Some("USD")),FakeExpense(Some(150), Some("US"), Some("USD"))))
无效报告:
val report = FakeReport(1, List(FakeExpense(Some(150), Some("US"), Some("USD")),FakeExpense(Some(85), Some("DE"), Some("EUR"))))
val report = FakeReport(2, List(FakeExpense(Some(150), Some("US"), Some("USD")),FakeExpense(Some(150), Some("US"), Some("USD"))))
谢谢 考虑这样的方法
def isValidReport(report: FakeReport): Boolean =
report.expenses.distinct.length == report.expenses.length
上述解决方案对列表进行了三次遍历。应用路易斯的评论,我们可以减少到两次这样的传球
def isValidReport(report: FakeReport): Boolean = {
report.expenses.sizeIs == report.expenses.iterator.distinct.length
}
因为distinct.length
在iterator.distinct.length
中折叠为单个转换,所以我们删掉了一个过程。这是一个潜在的快速节约,我们可能不必通读整个清单
这里是一个基于具有查找和插入功能的HashSet的单过程尾部递归解决方案
def isValidReport(report: FakeReport): Boolean = {
val set = mutable.HashSet[FakeExpense]()
@tailrec def loop(l: List[FakeExpense]): Boolean = l match {
case Nil => true
case h :: t => if (set.add(h)) loop(t) else false
}
loop(report.expenses)
}
还要注意我们如何在第一次复制时尽早返回。如果您需要完全相同的报告,而不考虑与epsilon的双重比较(|a-b |fakeReport.expenses.toSet.length==fakeReport.expenses.length
它将一直工作,直到类中要与==一起使用的所有内容都正确地实现了equals方法(基本类型、大多数默认类、case类和对象都这样做)。不能正确实现这一点的是数组,可能还有某些java类,这些类被包装到AnyVal类中 我会在第一个问题上使用
迭代器,然后使用sizeIs
来减少迭代次数。@LuisMiguelMejíaSuárez我不知道迭代器
是如何帮助的,但是我已经用基于哈希集
的单程解决方案更新了问题。迭代器
在distinct
之前将将迭代次数从两次减少到一次。@LuisMiguelMejíaSuárez啊,你的意思是因为iterator.distinct.length
变成了单个转换吗?是的,无论如何你的HashSet
解决方案更好:p