2011-09-20 32 views
1

比方说,我有2所列出:比较两个列表[CustomObject]在斯卡拉

val list1:List[CustomObject] = List(obj1, obj2, obj3) 
val list2:List[CustomObject] = List(obj4, obj5, obj6) 

我想知道是否有一种在Scala的做法,从第一个采取这些2所列出并进行比较,如果obj.name列表发生在第二个列表中。

这可以使用2个内部循环和一个标志来完成。但是,我想知道是否有什么可以做到这一点的斯卡拉。

+0

这是不是很清楚你到底想要什么。你能提供一个输入和预期输出的例子吗? –

+0

假设我们有一个类叫车有2个属性: carName&CarColor 现在我们有2所列出: 列表1 =名单(carObj1,carObj2,carObj3) 列表2 =名单(carObj4,carObj5,carObj6) 让我们假设carObj3.name == carObj4.name 我期望的结果: 结果:List [Car] = List [carObj1,carObj2,carObj5,carObj6] – Echo

+1

我已经想出了一个办法:val result = for(z <-list2 if!list1.contains(z)) 收益率z – Echo

回答

8

如果你想用比较进行排序的属性,那么这个工程:

import scala.collection.immutable.SortedSet 
val set1 = SortedSet(list1: _*)(Ordering by (_.name)) 
val set2 = SortedSet(list2: _*)(Ordering by (_.name)) 

val result = set1 &~ set2 union set2 &~ set1 
val result2 = set1 | set2 diff set1 & set2 // also works 

现在,如果这是不可能的,这个作品:

for { 
    x <- list1 ++ list2 // you want elements from both, right? 
    if list1.forall(_.name != x.name) || list2.forall(_.name != x.name) 
} yield x 

非常低效。为了使其高效,使用Map

def carName = (x: Car) => x.name -> x 
val map1 = (list1 map carName).toMap 
val map2 = (list2 map carName).toMap 
for { 
    x <- list1 ++ list2 // you want elements from both, right? 
    if map1(x).isEmpty || map2(x).isEmpty 
} yield x 
2

类似的东西这个应该工作

list1.exists(a => list2.exists(b => a.name == b.name)) 
+0

其实我有这样的感觉: val list1 = List(1,2,3,4,5) val list2 = List(5,6,7,8) val result = list1.map(x => {(list2.exists(l => l == x))== false) X }) 结果是 结果:列表[AnyVal] =列表(1,2,3,4,()) 如何可以只返回列表[INT] =列表(1,2, 3,4) 我相信我的问题的解决方案是进入折叠..呃仍然阅读它。 – Echo

0

的follwoing正常工作与我:

val comparisonResultList: List[Car] = 
     for (l1 <- list1 if list2.filter(_.referenceName==l1.referenceName)==Nil) 
     yield l1 

感谢所有为UR支持。