I found another question similar to the one I have, but I was not able to replicate it (probably because it doesn't deal with hashes neither have symbols).
So, given the following array of hashes:
[{:id=>1, :name=>"AA;AB;AC", :title=>"A row"},
{:id=>2, :name=>"BA;BB", :title=>"B row"},
{:id=>3, :name=>"CA", :title=>"C row"}]
I would like to achieve the following result:
[{:id=>1, :name=>"AA", :title=>"A row"},
{:id=>1, :name=>"AB", :title=>"A row"},
{:id=>1, :name=>"AC", :title=>"A row"},
{:id=>2, :name=>"BA", :title=>"B row"},
{:id=>2, :name=>"BB", :title=>"B row"},
{:id=>3, :name=>"CA", :title=>"C row"}]
In brief, I want to fully replicate a hash, splitting it by semicolon. In this case, :name have two hashes with one or more semicolons that should be split and consist on another hash.
I hope you have understand my question. Any help is highly appreciated.
CodePudding user response:
You could iterate over your array of hashes and split their name value, and map that result merging it with the current hash. Then you can flatten the result:
[
{:id=>1, :name=>"AA;AB;AC", :title=>"A row"},
{:id=>2, :name=>"BA;BB", :title=>"B row"},
{:id=>3, :name=>"CA", :title=>"C row"}
].flat_map do |hsh|
hsh[:name].split(";").map do |name|
hsh.merge(name: name)
end
end
# [{:id=>1, :name=>"AA", :title=>"A row"},
# {:id=>1, :name=>"AB", :title=>"A row"},
# {:id=>1, :name=>"AC", :title=>"A row"},
# {:id=>2, :name=>"BA", :title=>"B row"},
# {:id=>2, :name=>"BB", :title=>"B row"},
# {:id=>3, :name=>"CA", :title=>"C row"}]
CodePudding user response:
Using Enumerable#each_with_object
ary =
[
{ id: 1, name: "AA;AB;AC", title: "A row" },
{ id: 2, name: "BA;BB", title: "B row" },
{ id: 3, name: "CA", title: "C row" }
]
ary.each_with_object([]) do |hash, new_ary|
hash[:name].split(";").each do |name|
new_ary << hash.merge(name: name)
end
end
