【问题标题】:Compare an element of a list against all other elements将列表中的一个元素与所有其他元素进行比较
【发布时间】:2015-03-30 22:20:27
【问题描述】:

假设我有一个 Scala 列表,

val list : List[Set[Int]] = List(set1, set2, set3, set4)

我列表中的每个元素都是一组整数。

我正在寻找一种优雅的方式来创建一个列表,其中我的列表中的每个元素都与 所有 其他元素进行比较。例如,我可能想要生成一个列表,其中每个元素(集合)仅包含列表中任何其他元素中未包含的元素。

例如我有一些功能:

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

我想做类似于list.map(f(_, rest_of_list)) 的事情,而不必为每个元素构造rest_of_list。我现在能想到的唯一方法是使用slice,这使得它非常丑陋和低效,imo。

【问题讨论】:

    标签: list scala scala-collections


    【解决方案1】:

    您可以使用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
    

    因此,如果您想在 list 的元素之间映射您的函数 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)
    

    【讨论】:

    • 这比使用切片要漂亮几个数量级,但这仍然不是我所希望的。 (我的失望是针对 scala,而不是你的答案)
    • 嘿嘿,你用我所想的更好的版本更新了你的答案。地图方法是我接受的答案。
    【解决方案2】:

    我不知道它是否像你想要的那样优雅,但是一种更通用的方式可以用任何东西替换 '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
    }
    

    【讨论】:

      猜你喜欢
      • 2013-06-06
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2021-02-05
      • 1970-01-01
      • 1970-01-01
      • 2015-04-02
      • 2016-03-13
      相关资源
      最近更新 更多