Key and value mapping from one object to another I've been trying to figure out a clean way of managing mappings between two objects. In the case of this example, it's two hashes. This spec should illustrate the problem at hand:

describe 'key mapping' do
  let(:have) { { data1: 'foo', data2: 'bar', data3: 'baz' } }
  let(:want) { { LINE1: 'foo', LINE2: 'bar', LINE3: 'baz' } }
  let(:result) { {} }

  after(:each) do
    expect(result).to eq want
  end

  it 'by assigning manually' do
    result[:LINE1] = have[:data1]
    result[:LINE2] = have[:data2]
    result[:LINE3] = have[:data3]
  end

  it 'by reading keys from a hash' do
    mappings = { data1: :LINE1, data2: :LINE2, data3: :LINE3 }
    mappings.each do |k, v|
      result[v] = have[k]
    end
  end
end


The notable thing here is that the source and destination can be mapped by known keys and unlike in the example there is no numeric correlation between the source and destination (example lists numbered keys just to make it easier to read)

The number of keys could be rather high, so the latter example will make code more readable, but is there an even better way of handling this?
If there's no "logical" correlation between the key you have, and the key you want (i.e. no consistent way to rewrite them) then you basically have to use a lookup of some sort to do the translation.

So your "reading keys from a hash" strategy is your best bet, but it can be improved a little.

You can be more functional and just use map:

lookup = { data1: :LINE1, data2: :LINE2, data3: :LINE3 }

result = Hash[ lookup.map { |in, out| [out, have[in]] } ]


Or you can just go through the ones in the input hash, and translate the ones that are actually there, discarding ones without a translation:

result = Hash[ have.map { |k, v| [lookup[k], v] if lookup[k] }.compact ]


And for either of those, if you ever need to translate the other way, you can just use lookup.invert to flip the keys/values around.

Lastly, for you spec, don't put an expectation in a after(:each) block. Put the expectation in the spec itself.