Michael
Michael

Reputation: 42100

How to add optional entries to Map in Scala?

Suppose I am adding an optional entry of type Option[(Int, String)] to Map[Int, String]

def foo(oe: Option[(Int, String)], map: Map[Int, String]) = oe.fold(map)(map + _)

Now I wonder how to add a few optional entries:

def foo(oe1: Option[(Int, String)],
        oe2: Option[(Int, String)],
        oe3: Option[(Int, String)],
        map: Map[Int, String]): Map[Int, String] = ???

How would you implement it ?

Upvotes: 3

Views: 700

Answers (3)

Travis Brown
Travis Brown

Reputation: 139058

As I mention in a comment above, Scala provides an implicit conversion (option2Iterable) that allows you to use Option as a collection of one or zero objects in the context of other types in the collection library.

This has some annoying consequences, but it does provide the following nice syntax for your operation:

def foo(oe1: Option[(Int, String)],
    oe2: Option[(Int, String)],
    oe3: Option[(Int, String)],
    map: Map[Int, String]): Map[Int, String] = map ++ oe1 ++ oe2 ++ oe3

This works because the ++ on Map takes an GenTraversableOnce[(A, B)], and the Iterable that you get from option2Iterable is a subtype of GenTraversableOnce.

There are lots of variations on this approach. You could also write map ++ Seq(oe1, oe2, oe3).flatten, for example. I find that less clear, and it involves the creation of an extra collection, but if you like it, go for it.

Upvotes: 2

Andrew Cassidy
Andrew Cassidy

Reputation: 3008

If the number of optional entries is variable I would use variable length arguments

def foo(map: Map[Int, String], os: Option[(Int, String)]*) = map ++ os.flatten

Upvotes: 0

Madoc
Madoc

Reputation: 5919

map ++ Seq(oe1, oe2, oe3).flatten

Upvotes: 2

Related Questions