【问题标题】:Compare each element of Scala list against rest of elements in the list将 Scala 列表的每个元素与列表中的其余元素进行比较
【发布时间】:2015-04-02 11:31:59
【问题描述】:

我有一个自定义对象列表,将与同一列表中的其余对象进行比较。

我目前的方法:目前我使用 foreach 循环从列表中获取一个元素,运行另一个 foreach 循环以查看列表中与所取对象相似的元素。

case class TestOb(name:String,pos:Vector[Int])

val lis:List[TestOb] = null

lis.foreach{i=>
    val ref = i._2
    lis.foreach{j=>
        val current = j._2
        //compare ref and current.
    }
}

是否有任何其他有效的方法可以在同一个列表中的 Scala 中进行此迭代而无需两个 foreach 循环?

【问题讨论】:

  • 你能提供编译的代码,同时输入数据示例和预期结果吗?
  • 比较两个列表数据结构总是产生相同的线性运行时效率 O(2n),无论编程语言如何。您的问题是关于更有效的数据结构还是如何在 scala 中进行“惯用”列表比较?

标签: list scala foreach scala-collections


【解决方案1】:

您是否尝试过使用for-loop?

for( a <- lis; b <- lis) {
  // do stuff with a and b
}

为了进一步方便,这里有一个简单的例子来了解幕后的迭代:

scala> val list = 1 to 3
list: scala.collection.immutable.Range.Inclusive = Range(1, 2, 3)
scala> for(a <- list; b <- list) println(a+" - "+b)
1 - 1
1 - 2
1 - 3
2 - 1
2 - 2
2 - 3
3 - 1
3 - 2
3 - 3

就其价值而言,酶解决方案将更符合 scala 所采用的功能风格。

【讨论】:

    【解决方案2】:

    一种将集合中的每个元素与其余元素进行比较并收集那些相似的方法(这里通过在collect 中使用== 相同)。为了说明案例考虑

    case class C(i:Int)
    

    还有一个集合,其中C(1) 有一个similar 项目(这里是平等的),

    val xs = Array( C(1),C(2),C(3),C(1),C(4) )
    

    因此我们将每两个项目合并,比较它们并收集相似的,

    xs.combinations(2).collect { case Array(a,b) if a == b => a }.toArray
    Array(C(1))
    

    注意combinations 提供了一个迭代器,它被collect 使用(迭代)。另外,将collect 中的== 替换为dissimilarity 函数,用于比较项目以确定哪些足够相似。

    【讨论】:

    • 您能解释一下如何同时比较所有个元素而不是每个吗?看起来这减少到list.map(i=&gt;list.exists(_ == i)).zip(list).filter(_._1).map(_._2)(是的,这很丑)。
    • “所有同时”的近似值,xs.combinations(2).toArray.par.collect {case Array(a,b) if a == b => a}` ,即转换将组合迭代到并行集合中,在该集合上应用collect。这并不能确保同时评估所有元素,而是同时评估其中的几个。对于大型集合(组合),这可能会大大提高性能。
    猜你喜欢
    • 2013-06-06
    • 1970-01-01
    • 1970-01-01
    • 2019-01-19
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2017-10-30
    相关资源
    最近更新 更多