scalapattern-matching

Pattern matching large case classes without referring to unused fields


Consider the following Scala case class:

case class WideLoad(a: String, b: Int, c: Float, d: ActorRef, e: Date)

Pattern matching allows me to extract one field and discard others, like so:

someVal match {
    case WideLoad(_, _, _, d, _) => d ! SomeMessage(...)
}

What I would like to do, and what's more relevant when a case class has ~20 odd fields, is to extract only a few values in a way that does not involve typing out WideLoad(_, _, _, _, _, some, _, _, _, thing, _, _, interesting).

I was hoping that named args could help here, although the following syntax doesn't work:

someVal match {
    case WideLoad(d = dActor) => dActor ! SomeMessage(...)
    //              ^---------- does not compile
}

Is there any hope here, or am I stuck typing out many, many _, _, _, _?

EDIT: I understand that I can do case wl @ WideLoad(...whatever...) => wl.d, yet I'm still wondering whether there's even terser syntax that does what I need without having to introduce an extra val.


Solution

  • I don't know if this is appropriate, but you can also build an object just to match that field, or that set of fields (untested code):

    object WideLoadActorRef {
      def unapply(wl: WideLoad): Option[ActorRef] = { Some(wl.d) }
    }
    
    someVal match {
      case WideLoadActorRef(d) => d ! someMessage
    }
    

    or even

    object WideLoadBnD {
      def unapplySeq(wl: WideLoad): Option[(Int,ActorRef)] = { Some((wl.b,wl.d)) }
    }
    
    someVal match {
      case WideLoadBnD(b, d) => d ! SomeMessage(b)
    }