whats the scala way to filter a list of case classes

2,326 views
Skip to first unread message

Robby Pelssers

unread,
Nov 14, 2012, 8:55:16 AM11/14/12
to scala...@googlegroups.com
Hi all,

Suppose I have following case classes. I know I can do pattern matching to filter them out but it seems like a lot of boiler plate code.
Is there a more elegant way to accomplish this? I also know I can use isInstanceOf but that does not seem nice either.

Robby


object Test {
trait Move
case class Empty(glass: Int) extends Move
case class Fill(glass: Int) extends Move
case class Pour(from: Int, to: Int) extends Move

val moves = List(Empty(3), Fill(4), Empty(2), Pour(1,3), Fill(8))
//> List(Empty(3), Fill(4), Empty(2), Pour(1,3), Fill(8))

/** I'm only interested in the Fill moves **/
moves.filter(move => move match {
case Empty(n) => false
case Fill(n) => true
case Pour(n,o) => false
}) //> List(Fill(4), Fill(8))
}

Robby Pelssers

unread,
Nov 14, 2012, 9:01:04 AM11/14/12
to Robby Pelssers, scala...@googlegroups.com
Oh yes.. and while we're discussing this problem anyway..


What would be the way to go from a list of Moves to a list of Fills.. so first apply filtering and next I should be sure to only have Fills left and I want the end result to be a list of Fill.


def filterFills(moves: List[Move]): List[Fill] = ???

Johannes Rudolph

unread,
Nov 14, 2012, 9:38:49 AM11/14/12
to Robby Pelssers, scala...@googlegroups.com
Use collect:

moves.collect { case f: Fill => f }
--
Johannes

-----------------------------------------------
Johannes Rudolph
http://virtual-void.net

Axel Poigné

unread,
Nov 14, 2012, 12:21:35 PM11/14/12
to scala...@googlegroups.com
This might do

moves.filter ( _.isInstanceOf[Fill])

Axel

Razvan Cojocaru

unread,
Nov 14, 2012, 12:41:24 PM11/14/12
to Johannes Rudolph, Robby Pelssers, scala...@googlegroups.com
+1

Remember that { case f: Fill => f } by itself, is a PartialFunction...

cheers

Nicholas Sterling

unread,
Nov 14, 2012, 2:47:36 PM11/14/12
to scala...@googlegroups.com, robby.p...@nxp.com
There's a trick:

scala> for ( y@(x:Fill) <- moves ) println(x)
Fill(4)
Fill(8)

Erik Post

unread,
Nov 15, 2012, 6:33:06 AM11/15/12
to scala...@googlegroups.com, robby.p...@nxp.com
Hm, I don't think I'd call that a 'trick'. It's just that you can pattern match on the left hand side of a for comprehension. You could have written:

for (Fill(x) <- l) println(x)

in this case, since we're not referencing y later on.

Cheers,
Erik
 

Erik Post

unread,
Nov 15, 2012, 6:34:09 AM11/15/12
to scala...@googlegroups.com, robby.p...@nxp.com
Oops, I meant: for (Fill(x) <- moves) println(x)
Reply all
Reply to author
Forward
0 new messages