Showing posts with label code. Show all posts
Showing posts with label code. Show all posts

Monday, September 5, 2016

Rollup "map" from an Array to a Dictionary

I've often found myself doing work taking a sequence (usually an Array) of things and turning them into a Dictionary (key -> value mapping). Whenever I find myself doing something similar a few too many times, I find it's time to write a bit of reusable code, hence rollup.
rollup is three functions to provide an interface for taking a sequence of items and making a dictionary out of them. Here are the three cases I handled:
  • A) I have a sequence of Keys, so I provide a function that maps each Key to a Value to fill out the dictionary.
  • B) I have a sequence of Values, so I provide a function that maps each Value to a Key to fill out the dictionary.
  • C) I have a sequence of Things, so I provide a function that maps each Thing to a Key & Value to fill out the dictionary.
Let's see how we might use each.
A) I have the Keys
someKeys.rollupKeys({ (key) in valueForKey(key) })

B) I have the Values
someValues.rollup({ (value) in value.keyAttribute })

C) I have some Things
someThings.rollup({ (thing) in (thing.keyAttribute, thing.valueAttribute) })

Why does (A) use the name rollupKeys() for it's function? The short answer is compiler confusion. Let's use a simple example and say I want to use String as the type for both keys and values. The compiler would have no way to tell which version of rollup() I was trying to use because the function from a Key to a Value is identical to a function from a Value to a Key in this case. So I'm choosing to make life simpler for (B) as that is the more frequent usage of this rollup() behavior in my own experience.

Here is the current code for Rollup as a Gist, and some important Note/Warning below…


I should also note, one flaw with these as they are is that they do NOT gracefully handle situations where you have more than one Value for the same Key. These functions, as written today, will return the LAST Key->Value mapping seen by going thru the sequence in order, so you would lose any other values that shared a common key. Arguably, a better interface might be to have these functions be called flatrollup() and use rollup to map things into a dictionary of type [Key: [Value]] to handle the overflow problem. Then you would get an array of multiple items whenever you provided multiple values for the key. If you make such code, please tweet me and I would be happy to share your solution.