This page is no longer maintained — Please continue to the home page at www.scala-lang.org

Can you pattern match a (key,value) pair from Map?

3 replies
tolsen77
Joined: 2008-10-08,
User offline. Last seen 1 year 38 weeks ago.
Is is possible to pattern match against a (key,value) pair of Map link in the example below? It's mostly for convenience so I don't need to do an additional if test.

Example that fails:

sealed case class Attrib(name: String, attribs: Map[String,Attrib])

val a = Attrib("a", Map(("b", Attrib("c", Map()))))

a match
{
    case Attrib("a",("b",attribs)) => println("Found " + attribs)
    case _ =>  println("No match")
}

Rich Dougherty 2
Joined: 2009-01-19,
User offline. Last seen 42 years 45 weeks ago.
Re: Can you pattern match a (key,value) pair from Map?

On Mon, Feb 16, 2009 at 7:37 PM, Trond Olsen wrote:
> Is is possible to pattern match against a (key,value) pair of Map link in
> the example below? It's mostly for convenience so I don't need to do an
> additional if test.
>
> Example that fails:
>
> sealed case class Attrib(name: String, attribs: Map[String,Attrib])
>
> val a = Attrib("a", Map(("b", Attrib("c", Map()))))
>
> a match
> {
> case Attrib("a",("b",attribs)) => println("Found " + attribs)
> case _ => println("No match")
> }

Hi Trond

Map uses an unordered hash internally (at least once it is 5 big), so
I don't think you'd be able to guarantee which item you would pattern
match against. You might be able to get something working with
ListMap, although I don't see any ordering guarantees in its docs.

In your code above you could also replace Map with Option, but I guess
that's because "a" is just a simple example value.

Cheers
Rich
--
http://www.richdougherty.com/

tolsen77
Joined: 2008-10-08,
User offline. Last seen 1 year 38 weeks ago.
Re: Can you pattern match a (key,value) pair from Map?
I think I see what you mean, if I pattern matched against the value in the (key,value) pair with the key open, it would get into problems? Anyway, a if is preferable to pondering further on this. :)

On Mon, Feb 16, 2009 at 9:21 AM, Rich Dougherty <rich@nil.co.nz> wrote:
On Mon, Feb 16, 2009 at 7:37 PM, Trond Olsen <tolsen77@gmail.com> wrote:
> Is is possible to pattern match against a (key,value) pair of Map link in
> the example below? It's mostly for convenience so I don't need to do an
> additional if test.
>
> Example that fails:
>
> sealed case class Attrib(name: String, attribs: Map[String,Attrib])
>
> val a = Attrib("a", Map(("b", Attrib("c", Map()))))
>
> a match
> {
>     case Attrib("a",("b",attribs)) => println("Found " + attribs)
>     case _ =>  println("No match")
> }

Hi Trond

Map uses an unordered hash internally (at least once it is 5 big), so
I don't think you'd be able to guarantee which item you would pattern
match against. You might be able to get something working with
ListMap, although I don't see any ordering guarantees in its docs.

In your code above you could also replace Map with Option, but I guess
that's because "a" is just a simple example value.

Cheers
Rich
--
http://www.richdougherty.com/

Rich Dougherty 2
Joined: 2009-01-19,
User offline. Last seen 42 years 45 weeks ago.
Re: Can you pattern match a (key,value) pair from Map?

On Mon, Feb 16, 2009 at 9:55 PM, Trond Olsen wrote:
> I think I see what you mean, if I pattern matched against the value in the
> (key,value) pair with the key open, it would get into problems? Anyway, a if
> is preferable to pondering further on this. :)

Yes, I think you're right. :-)

Anyway, here's a way to match a value for a known key, but it's not very nice!

case class ValueFor[A,B](key: A) {
def unapply(map: Map[A,B]): Option[B] = map.get(key)
}

val m = Map(("a", 2))
val valueForA = ValueFor("a")
m match {
case valueForA(value) => println(value)
}

Cheers
Rich

Copyright © 2012 École Polytechnique Fédérale de Lausanne (EPFL), Lausanne, Switzerland