【问题标题】:Scala: behavior of filter on Iterator vs. ListScala:迭代器与列表上的过滤器行为
【发布时间】:2015-07-27 16:59:27
【问题描述】:
$ 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]

// 鉴于过滤器的这个定义,我希望下面的表达式(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) 和 (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))

【问题讨论】:

    标签: list scala filter iterator


    【解决方案1】:

    问题 #1:下面的表达式 (2) 是如何工作的?它从哪里获得 A => 布尔推断?我的意思是问,布尔值是从哪里来的?

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

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

    问题 #2:(1) 和 (2) 哪个更好,为什么?在 List 上尝试了同样的事情,我希望这能奏效。

    哪个更好更多是见仁见智的问题-在功能上它们完全相同。对于那些熟悉Set 的人来说,应该清楚它们的作用(它们都等同于contains)。 可能说使用Set(1, 2, 3).contains 可以更清楚地了解它的作用。 List 有一个 apply 方法,但与 Set 不同。 List#apply 是 Int =&gt; A -- 一种通过索引从 List 检索元素的方法。所以对于列表,你必须使用contains。

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

    这真的和#2一样。 List(1, 2, 3).apply 不是Int =&gt; Boolean,而是Int =&gt; Int。

    【讨论】:

      【解决方案2】:

      答案 #1

      filter(Set(1,2,3)) 起作用的原因是 Set 有一个 apply 方法可以影响 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
      }
      

      【讨论】:

        猜你喜欢
        • 2014-10-27
        • 1970-01-01
        • 2019-07-08
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 2018-04-26
        • 1970-01-01
        • 2012-01-14
        相关资源
        最近更新 更多