How to combine filter and map in Scala?

后端 未结 6 548
不知归路
不知归路 2020-12-28 13:10

I have List[Int] in Scala. The List is List(1,2,3,4,5,6,7,8,9,10). I want to filter the list so that it only has even numbers. And I w

相关标签:
6条回答
  • 2020-12-28 13:35

    As I state in my comment, collect should do what you want:

    list.collect{
      case x if x % 2 == 0 => x*2
    }
    

    The collect method allows you to both specify a criteria on the matching elements (filter) and modify the values that match (map)

    And as @TravisBrown suggested, you can use flatMap as well, especially in situations where the condition is more complex and not suitable as a guard condition. Something like this for your example:

    list.flatMap{
      case x if x % 2 == 0 => Some(x*2)
      case x => None
    }
    
    0 讨论(0)
  • 2020-12-28 13:36

    I tend to like the filter approach.

    val list1 = List(1,2,3,4,5,6,7,8,9,10)
    list1.filter(x => x%2 == 0).map(_*2)
    
    0 讨论(0)
  • 2020-12-28 13:41

    As @cmbaxter said, collect suits your need perfectly. The other nice thing about collect is that it figures out resulting type in case you're filtering by class:

    scala> trait X
    // defined trait X
    
    scala> class Foo extends X
    // defined class Foo
    
    scala> class Bar extends X
    // defined class Bar
    
    scala> val xs = List(new Foo, new Bar, new Foo, new Bar)
    // xs: List[X] = List(Foo@4cfa8227, Bar@78226c36, Foo@3f685162, Bar@11f406f8)
    
    scala> xs.collect { case x: Foo => x }
    // res1: List[Foo] = List(Foo@4cfa8227, Foo@3f685162)
    

    On par, filter can't be that smart (see List[Foo] vs List[X]):

    scala> xs.filter { case x: Foo => true; case _ => false }
    // res3: List[X] = List(Foo@4cfa8227, Foo@3f685162)
    
    0 讨论(0)
  • 2020-12-28 13:49

    This should do the work for you:

    Filter first when the condition is p % 2 == 0 (for getting only even numbers).

    And then use map to multiply those even numbers by 2.

    var myList = List(1,2,3,4,5,6,7,8,9,10).filter(p => p % 2 == 0).map(p => {p*2})
    
    0 讨论(0)
  • 2020-12-28 13:55

    How about a good old fashioned fold?

    xs.foldLeft(List[Y]()) { (ys, x) => 
        val z = calculateSomethingOnX(x)
        if (someConditionOnZ(z)) 
            Y(x, z) :: ys
        else 
            ys
    }
    
    0 讨论(0)
  • 2020-12-28 13:57

    A for comprehension (which internally unfolds into a combination of map and withFilter) as follows,

    for (x <- xs if x % 2 == 0) yield x*2
    

    Namely

    xs.withFilter(x => x % 2 == 0).map(x => x*2)
    
    0 讨论(0)
提交回复
热议问题