TL;DR
Dale Emery @dhemery ask this question on Twitter. I responded with Gist solution.
The Problem
Is there a canonical/idiomatic way in Ruby 2+ to invert a hash whose values are arrays, so that the resulting hash uses the values in the arrays as its keys?
— Dale Emery (@dhemery) January 15, 2019
As a software tester, I asked for data as an example for input for this problem (note the Imagine word, which suggests that I needed to create a model of Dale’s explanation):
and what values should be paired with those keys? Example?
— Karlo Smid (@karlosmid) January 15, 2019
Example: Imagine a hash that maps each date to a list people born on that date. I want to invert that to a hash that maps each person to their date of birth.
— Dale Emery (@dhemery) January 15, 2019
The Solution
I was ready to tackle this problem. Here is the solution, in gist:
Code Review
Note the name of ruby function. It is no do_something, but reverse_birthdays. After a several days, by just reading its name, I know what does it do.
Second line is result container, empty at the start.
Third line does the actual work. Map function works on Hash. Hash is the input for reverse_birthdays. Map takes every Hash pair (day, names), and modifies it. Note the idiom |day,names|. I often see something like |k,v|, which is shorthand for |key,value|. It is better to use names what key and value represent, in this case, day and names. Plural indicates Array. So code takes every (day, names) pair, then for every names Array, takes every name in that Array using map function and creates new result Hash element that has for key name, and for value day.
Fourth line returns resulting hash.
Sixth line is data input, explained by Dale in his Tweet. Variable actual to denote original data. Ruby Hash is data sets of key, value pairs. In this example, values are assigned to key with =>, and Hash is denoted with { }. Array values are denoted with [ ]. In Python, Hash is called Dictionary, in Elixir it is map.
Seventh line is expected result, reverse Hash of input Hash.
Last line is a test (just joking, it is a check) for reverse_birthdays function. It returns true.
There are 5 revisions of this simple function, because while I was writing this post, I realized that first version returned Array of Hashes, instead of one Hash. Click revisions, and you will see the evolution of reverse_birthdays functions.