Scala:Iterator与List上的过滤器行为

时间:2015-05-15 17:07:55

标签: list scala filter iterator

$ scala
Welcome to Scala version 2.10.4 (Java HotSpot(TM) 64-Bit Server VM, Java 1.7.0_79).
Type in expressions to have them evaluated.
Type :help for more information.

scala> Iterator(2,4,6)
res0: Iterator[Int] = non-empty iterator

scala> res0.filter
filter      filterNot

scala> res0.filter
                                           def filter(p: A => Boolean): Iterator[A]

//鉴于filter的这个定义,我希望下面的表达式(1)能够工作:

scala> Iterator(2,4,6).filter(Set(1,2,3).contains).toSet
res1: scala.collection.immutable.Set[Int] = Set(2)

// 问题#1:以下表达式(2)如何工作?它从哪里得到A => Boolean推论?我想问一下,布尔来自哪里?

scala> Iterator(2,4,6).filter(Set(1,2,3)).toSet
res2: scala.collection.immutable.Set[Int] = Set(2)

// 问题#2 :哪个更好表达(1)vs(2)以及为什么?

//在List上尝试了相同的事情,我希望这可以工作。

 scala> List(2,4,6).filter(List(1,2,3).contains)
    res3: List[Int] = List(2)

// 问题#3:为什么当它为Iterator神奇地工作时这不起作用?

scala>  List(2,4,6).filter(List(1,2,3))
<console>:8: error: type mismatch;
 found   : Int(1)
 required: Boolean
               List(2,4,6).filter(List(1,2,3))

2 个答案:

答案 0 :(得分:2)

  

问题#1:以下表达式(2)如何工作?它在哪里获得A =&gt;布尔推断来自?我想问一下,布尔来自哪里?

Set[A] extends (A) => Boolean,因此Set(1, 2, 3) 是一个函数A => Boolean。我们可以很容易地看到,因为它有一个apply方法来测试Set中是否包含一个元素。

scala> Set(1, 2, 3)(2)
res22: Boolean = true
  

问题2:哪个更好表达(1)vs(2)以及为什么?在List上尝试了相同的事情,我希望这可以工作。

哪一个更好是更多的意见问题 - 功能上它们完全相同。对于那些熟悉Set的人,应该清楚是什么(它们都等同于contains)。一个可能说使用Set(1, 2, 3).contains会使其更明显地表达它的作用。 List有一个apply方法,但与Set不同。 List#applyInt => A - 一种通过索引从List检索元素的方法。因此,对于列表,您必须使用contains

  

问题3:为什么当它对Iterator神奇地起作用时,这不起作用?

这与#2 非常相似。 List(1, 2, 3).apply不是Int => Boolean,而是Int => Int

答案 1 :(得分:1)

回答#1

filter(Set(1,2,3))的作用原因是Setapply方法影响contains

class Set[T] { 
  def apply(elem: T): Boolean
}

回答#2

它们完全相同。

回答#3

这也是List(2,4,6).filter(List(1,2,3))不起作用的原因。如果你尝试了List(2,4,6).filter(Set(1,2,3)),那就可以了。 List的apply是列表中某个位置的访问者:

class List[T] {
  def apply(n: Int): Int
}