我有两个已定义的案例类和两个列表,如下面的代码。
case class Person(name: String, company: String, rank: Int, id: Long)
case class Employee(company: String, rank: Int, id: Long)
val persons = List(Person("Tom", "CompanyA", 1, null), Person("Jenny", "CompanyB", 1, null), Person("James", "CompanyA", 2, null))
val employees = List(Employee("CompanyA", 1, 1001), Employee("CompanyB", 1, 1002), Employee("CompanyA", 2, 1003))
由于company
和rank
的组合是唯一的,所以我想使用employees
中的信息,以便可以将两个列表合并为以下列表(“人”列表ID已满)。
[Person("Tom", "CompanyA", 1, 1001), Person("Jenny", "CompanyB", 1, 1002), Person("James", "CompanyA", 2, 1003)]
我试图这样实现:
zipBasedOnCondition(persons, employees, (person, employee) => person.name == employee.name && person.rank === employee.rank)
但是,我未能提出实现zipBasedOnCondition
功能的解决方案
有什么办法可以合并两个列表?
答案 0 :(得分:3)
您想要的可以通过以下方式实现:
for {
person <- persons
employee <- employees
if person.name == employee.name && person.rank === employee.rank
} yield person.copy(id = employee.id)
它的时间复杂度为O(persons.size * employees.size),但是由于List
无法保证内部事物被排序(尤其是要根据您要比较的事物进行排序),因此您无法对其进行优化。
如果需要,您可以对其进行修改,以使其采用可能的第一个配对,尽管这超出了“带条件的zip”的范围。
答案 1 :(得分:0)
我仍在寻找更好的解决方案...但这应该可行:
def f(c: String): Option[Employee] = employees.filter(_.company == c).headOption
for {
p <- persons
e <- f(p.company)
} yield {
p.copy(id = e.id)
}
答案 2 :(得分:0)
这将是一种非常通用的方法:
def zipBasedOnCondition[A, B, C](as: List[A], bs: List[B], pred: (A, B) => Boolean, f: (A, B) => C): List[C] = {
as.map(a => f(a, bs.filter(b => pred(a, b)).head))
}
然后您可以这样称呼它:
zipBasedOnCondition[Person, Employee, Person](persons, employees, (p, e) => p.name == e.name && p.rank == e.rank, (a, b) => a.copy(id = b.id))
zipBasedOnCondition
的实现将需要改进,因为它假定每个人对象都有一个对应的员工对象。
答案 3 :(得分:0)
您将在Person类中提供id字段作为必填字段,并在person列表中提供空值,这将产生错误。 首先,让我们更正您的Person类。
case class Person(name: String, company: String, rank: Int, id: Long = 0)
现在,解决您的问题。
def combineList( list1: List[Person], list2: List[Employee]): List[(Person)] = {
(for{
a <- list1
b <- list2
if (a.company == b.company && a.rank == b.rank)
} yield (a.copy(id = b.id)))
}
输出
List(Person(Tom,CompanyA,1,1001), Person(Jenny,CompanyB,1,1002), Person(James,CompanyA,2,1003))