3

I have a set of keys, say Set[MyKey] and for each of the keys I want to compute the value through some value function, lets say computeValueOf(key: MyKey). In the end I want to have a Map which maps key -> value

What is the most efficient way to do this without iterating too much?

jbx
  • 21,365
  • 18
  • 90
  • 144

2 Answers2

3

A collection of Tuple2s can be converted to a Map, where the tuple's first element will be the key and the second element will be the value.

val setOfKeys = Set[MyKey]()
setOfKeys.map(key => (key, computeValueOf(key)).toMap
Akos Krivachy
  • 4,915
  • 21
  • 28
  • Oh silly me, of course. I was going around in circles why the `toMap` function and related ones all expected the value in a tuple, which is why I asked the question. Still so green in this :(. Thanks as always!! – jbx Nov 15 '13 at 19:27
  • No problem. It takes a while until you know all the functions and what they do and after that they become a second nature. And if you switch to another language you'll **really** start to miss them :) – Akos Krivachy Nov 15 '13 at 19:31
  • Yes, I have started to use Scala after years of using Java. I am enjoying it so far, but still can't find my way through the obvious (as you can see from my questions today) which tends to get frustrating sometimes. – jbx Nov 15 '13 at 19:35
2

This is actually a pretty neat application for collection.breakOut, one of my favorite pieces of bizarre Scala voodoo:

type MyKey = Int

def computeValueOf(key: MyKey) = "value" * key
val mySet: Set[MyKey] = Set(1, 2, 3)

val myMap: Map[MyKey, String] =
  mySet.map(k => k -> computeValueOf(k))(collection.breakOut)

See this answer for some discussion of what's going on here. Unlike the version with toMap, this won't construct an intermediate Set, saving you some allocations and a traversal. It's also much less readable, though—I only offer it because you mentioned that you wanted to avoid "iterating too much".

Community
  • 1
  • 1
Travis Brown
  • 138,631
  • 12
  • 375
  • 680
  • Does this avoids more iterations than `setOfKeys.iterator.map(key => (key, computeValueOf(key)).toMap`? – scand1sk Nov 15 '13 at 23:48
  • Thanks for your answer. I still need to understand it a bit more. Yes, the reason I ask to avoid iterations as much as possible is because the problem I am working on is a bit combinatorial, so saving on iterations and `lazy val`ing where it makes sense should help. – jbx Nov 16 '13 at 11:01
  • @TravisBrown , could you please explain a bit more what the `collection.breakOut` is doing? Where is the keyword `collection` coming from? Its not declared anywhere but it works. Thanks – jbx Nov 17 '13 at 01:16
  • `collection` is just the `scala.collection` package (you can always omit the `scala.` part). Explaining `breakOut` is tricky—see Daniel Sobral's answer (linked above) for a really comprehensive attempt. In short, it says something like "find a builder that will construct the appropriate collection type and use it during the map". – Travis Brown Nov 17 '13 at 01:34