Warning: file_get_contents(/data/phpspider/zhask/data//catemap/2/scala/16.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
Scala 如何基于另一个不同类型的集合选择集合元素?_Scala - Fatal编程技术网

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())?无论如何,我遗漏了一些东西。@WillIAm
Set.contains
比List.contains更有效。你为什么认为它效率低下?你做过任何性能测量吗?基于将
y
转换为
Set
我认为第一种方法就足够了。你的意思是使用第一种方法(Set上的匹配)还是第二种方法(contains())?无论如何,我遗漏了一些东西。@WillIAm
Set.contains
List.contains更有效。严格地说,如果散列函数将
y
的元素很好地分布,它只是线性的。是的,很好。。。严格地说,只有当散列函数很好地分布
y
的元素时,它才是线性的。。。正如它得到的线性:)set look up()是一个常数时间操作@Dima解决方案会更好。set look up()是一个常量时间操作@Dima解决方案会更好。