The is a question about Transproc, though I hope to incorporate it into some work with dry-rb libraries as well. If this is the wrong place for the question, I’d be happy to repost elsewhere.
What is the best way to unwrap a multi-level nested hash? Say, for an arbitrary working example, I have an api that provides children’s answers to “what do you want to be when you grow up?”. Let’s say the data from the api looks something like this:
[
{
name: "Sally",
current_interest: {
level: 8,
summary: {
name: "NASA Engineer"
}
}
},
{
name: "Bob",
current_interest: {
level: 6,
summary: {
name: "Data analyst" # every kid's dream :)
}
}
}
]
For the purpose of another app, the data needs to be mapped to:
[
{
name: "Sally",
interest_level: 8,
interest_name: "NASA Engineer"
},
{
name: "Sally",
interest_level: 6,
interest_name: "Data analyst"
}
]
I want to unwrap :current_interest
and it’s :summary
into the top-level hash and rename it’s keys. My current implementation is:
require "spec_helper"
RSpec.describe "Unwrapping multi-level nested hash" do
let(:input) do
[
{
name: "Sally",
current_interest: {
level: 8,
summary: {
name: "NASA Engineer"
}
}
},
{
name: "Bob",
current_interest: {
level: 6,
summary: {
name: "Data analyst" # every kid's dream :)
}
}
}
]
end
let(:output) do
[
{
name: "Sally",
interest_level: 8,
interest_name: "NASA Engineer"
},
{
name: "Sally",
interest_level: 6,
interest_name: "Data analyst"
}
]
end
T = Module.new do
extend Transproc::Registry
import Transproc::HashTransformations
end
specify do
step_one = T[:unwrap, :current_interest, [:level, :summary], prefix: true]
step_two = T[:unwrap, :current_interest_summary, [:name], prefix: true]
step_three = T[
:rename_keys,
current_interest_level: :interest_level,
current_interest_summary_name: :interest_name,
]
expect(
(step_one >> step_two >> step_three).call(input[0])
).to eql(output[0])
end
end
Is there a better approach? Is there a transformation that can more directly unwrap the multi-level nesting? Or is multiple transformation one step at a time the right way to go?