Scala 如何基于另一个不同类型的集合选择集合元素?
我知道我能做到:Scala 如何基于另一个不同类型的集合选择集合元素?,scala,Scala,我知道我能做到: scala> val a = List(1,2,3) a: List[Int] = List(1, 2, 3) scala> val b = List(2,4) b: List[Int] = List(2, 4) scala> a.filterNot(b.toSet) res0: List[Int] = List(1, 3) 但我希望根据其整数键选择集合的元素,如下所示: case class N (p: Int , q: Int) val x = Li
scala> val a = List(1,2,3)
a: List[Int] = List(1, 2, 3)
scala> val b = List(2,4)
b: List[Int] = List(2, 4)
scala> a.filterNot(b.toSet)
res0: List[Int] = List(1, 3)
但我希望根据其整数键选择集合的元素,如下所示:
case class N (p: Int , q: Int)
val x = List(N(1,100), N(2,200), N(3,300))
val y = List(2,4)
val z = .... ?
Z // want Z to be ((N1,100), (N3,300)) after removing the items of type N with 'p'
// matching any item in list y.
我知道有一种方法可以做到这一点,它类似于下面的方法,可以让上面的代码正常工作:
val z = x.filterNot(e => y.contains(e.p))
但这似乎效率很低。有更好的方法吗?包含的
的问题是搜索将是线性搜索,您正在寻找O(N^2)
解决方案(如果数据集不大,这仍然可以)
无论如何,一个简单的解决方案可以是使用二进制搜索来获得O(NlnN)
解决方案。您可以轻松地将valy从列表转换为数组,然后使用java的二进制搜索方法
scala> case class N(p: Int, q: Int)
defined class N
scala> val x = List(N(1, 100), N(2, 200), N(3, 300))
x: List[N] = List(N(1,100), N(2,200), N(3,300))
scala> val y = Array(2, 4) // Using Array directly.
y: Array[Int] = Array(2, 4)
scala> val z = x.filterNot(e => java.util.Arrays.binarySearch(y, e.p) >= 0)
z: List[N] = List(N(1,100), N(3,300))
contains
的问题是,搜索将是线性搜索,您正在寻找O(N^2)
解决方案(如果数据集不大,这仍然可以)
无论如何,一个简单的解决方案可以是使用二进制搜索来获得O(NlnN)
解决方案。您可以轻松地将valy从列表转换为数组,然后使用java的二进制搜索方法
scala> case class N(p: Int, q: Int)
defined class N
scala> val x = List(N(1, 100), N(2, 200), N(3, 300))
x: List[N] = List(N(1,100), N(2,200), N(3,300))
scala> val y = Array(2, 4) // Using Array directly.
y: Array[Int] = Array(2, 4)
scala> val z = x.filterNot(e => java.util.Arrays.binarySearch(y, e.p) >= 0)
z: List[N] = List(N(1,100), N(3,300))
照办
val z = y.toSet
x.filterNot {z.contains(_.p)}
这是线性的。就这么做吧
val z = y.toSet
x.filterNot {z.contains(_.p)}
这是线性的。为什么你认为它效率低下?你做过任何性能测量吗?基于将y
转换为Set
我认为第一种方法就足够了。你的意思是使用第一种方法(Set上的匹配)还是第二种方法(contains())?无论如何,我遗漏了一些东西。@WillIAmSet.contains
比List.contains更有效。你为什么认为它效率低下?你做过任何性能测量吗?基于将y
转换为Set
我认为第一种方法就足够了。你的意思是使用第一种方法(Set上的匹配)还是第二种方法(contains())?无论如何,我遗漏了一些东西。@WillIAmSet.contains
比List.contains更有效。严格地说,如果散列函数将y
的元素很好地分布,它只是线性的。是的,很好。。。严格地说,只有当散列函数很好地分布y
的元素时,它才是线性的。。。正如它得到的线性:)set look up()是一个常数时间操作@Dima解决方案会更好。set look up()是一个常量时间操作@Dima解决方案会更好。