rubyruby-hash

Split text in hash value into new hash using separator in Ruby


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.


Solution

  • 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"}]