Scala: Filter Behavior on Iterator vs. List

$ 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]

      

// Given this filter definition, I would expect the following expression (1) to work:

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

      

// Question # 1: How does the following expression (2) work? Where does he get his output from A => Boolean

? I wanted to ask where does the bulin come from?

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

      

// Question # 2 : Which one is the best expression (1) vs (2) and why?

// Tried the same on List and I expected it to work.

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

      

// Question # 3: Why doesn't this work when it magically worked for an 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))

      

+3


source to share


2 answers


Question # 1: How does the following expression (2) work? Where does it get the inference A => Boolean? I wanted to ask where does the bulin come from?

Set[A] extends (A) => Boolean

, so it Set(1, 2, 3)

is a function A => Boolean

. We can see easily as it has an apply method that checks if an element is contained in Set

.

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

      

Question # 2: Which one is the best expression (1) vs (2) and why? Tried the same on List and I expected it to work.



Which one is better is more of a question - functionally they are exactly the same. For those familiar with it Set

, it should be clear that either does (they are both equivalent contains

). It can be said that the use Set(1, 2, 3).contains

makes it more obvious what it is doing. A List

has a method of application, but not the same as Set

. List#apply

- Int => A

- a method for retrieving an item from an index List

by index. Therefore, for lists, you should use contains

.

Question # 3: Why doesn't this work when it magically works for an Iterator?

This is really the same as # 2 . List(1, 2, 3).apply

no Int => Boolean

, it is Int => Int

.

+2


source


Answer # 1

The reason filter(Set(1,2,3))

is that it Set

has a method apply

that shadows contains

:

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

      

Answer # 2



They are identical.

Answer # 3

That's why it List(2,4,6).filter(List(1,2,3))

doesn't work. If you tried it List(2,4,6).filter(Set(1,2,3))

, it would work. The list is used to access the position in the list:

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

      

+1


source







All Articles