15

Basically I need to get a set of values from a map for a keys in a given list (in the same order keys are given).

val kv = Map("k3" -> "v3", "k1" -> "v1", "k2" -> "v2")
val ks = List("k1", "k2")

The best I could have improvised is foldRight over ks:

scala> (ks foldRight List[String]()) { (v, a) => kv(v) :: a }
res7: List[String] = List(v1, v2)

Are there any more convenient ways to do this in standard lib or just the shorter code, ideally something alike kv getVals ks? :)

Question is not so important of course, just trying to explore towards good style.

1
  • Wouldn't foldLeft be a better option here? It would be a better style I think, because it is implemented by iteration while foldRight is implemented by recursion in List.scala. Commented Jul 4, 2014 at 8:44

2 Answers 2

30

Or:

ks collect kv

The result is composed of all the values of kv for which a key is in ks.

(Besides being a Function a Map is also a PartialFunction)

Sign up to request clarification or add additional context in comments.

2 Comments

Great, collect happens to be safe variant when keys might be missing.
+1 I think this is as good as it gets. How blind was I to not exploit Map being a PartialFunction.
21

Use flatMap:

 ks flatMap { k => kv get k }

Or better:

 ks flatMap (kv get)

And with for comprehensions:

for (k <- ks; v <- kv get k) yield v

But none are as succinct or as clear as your own one-liner: :-)

ks map kv
List("k42") map kv // will barf

However, note that this is exceptional - it may throw an exception if ks contains a key not defined in the map kv.

Comments

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.