List 将列表中的一个元素与所有其他元素进行比较

List 将列表中的一个元素与所有其他元素进行比较,list,scala,scala-collections,List,Scala,Scala Collections,假设我有一个Scala列表 val list : List[Set[Int]] = List(set1, set2, set3, set4) 其中列表中的每个元素都是一组整数 我正在寻找一种优雅的方法来创建一个列表,其中列表中的每个元素都与其他元素进行比较。例如,我可能希望生成一个列表,其中每个元素(集合)只包含列表中任何其他元素中不包含的元素 e、 g.我有一些功能: def f(element : Set[Int], rest_of_list : List[Set[Int]]) : Set

假设我有一个Scala列表

val list : List[Set[Int]] = List(set1, set2, set3, set4)
其中列表中的每个元素都是一组整数

我正在寻找一种优雅的方法来创建一个列表,其中列表中的每个元素都与其他元素进行比较。例如,我可能希望生成一个列表,其中每个元素(集合)只包含列表中任何其他元素中不包含的元素

e、 g.我有一些功能:

def f(element : Set[Int], rest_of_list : List[Set[Int]]) : Set[Int]

我想做一些类似于
list.map(f(\u,rest\u of\u list))
的事情,而不必为每个元素构造
rest\u of\u list
。我现在能想到的唯一方法就是使用
slice
,这使得它非常难看和低效,我想。

你可以使用
diff
而不是
slice

 list.map(set => set diff (list diff List(set)).flatten.toSet)
 //Alternative with filterNot
 list.map(set => set.filterNot((list diff List(set)).flatten.contains))  
diff
在这里工作,因为它只删除元素的一个实例,而且
Set[Int]
有一个很好的
equals
方法:

List(Set(1), Set(1, 2)) diff List(Set(1)) //List(Set(1, 2))
List(Set(1), Set(1)) diff List(Set(1)) //List(Set(1))
因此,将一个集合映射到列表中所有其他集合的列表:

val setWithOthers = list.map(set => set -> (list diff List(set)))
val setWithOthers = (list, list.map(list diff List(_))).zipped.toList //equivalent, less efficient
因此,如果您想跨
列表的元素映射函数
f
,可以执行以下操作:

setsWithOthers.map { case(set, others) => f(set, others) }
setsWithOthers.map(kvp => f(kvp._1, kvp._2))
setsWithOthers.map((f _).tupled)
您还可以创建完整的多重集,该多重集跟踪每个元素出现的次数。然后,在循环的每次迭代中,可以从完整的多集中“减去”一个集:

val multiset = list.flatten.groupBy(identity).mapValues(_.length)

我不知道它是否像你想要的那样优雅,但有一种更一般的方式,你可以用任何东西来代替“f”:

val list = List(Set(1,2,3,4),Set(1,2),Set(1,3))

list.map(e => f(e,list.filterNot(_==e)))
//res0: List[Set[Int]] = List(Set(4), Set(), Set())

def f(element : Set[Int], rest_of_list : List[Set[Int]]) : Set[Int] = {
  (element.toList diff rest_of_list.flatten.toList).toSet
}

这比使用切片要漂亮几个数量级,但这仍然不是我所希望的。(我的失望是针对scala的,不是你的答案)呵呵,你更新了你的答案,用了一个更好的版本来表达我的想法。地图方法是我接受的答案。