简体   繁体   中英

Merge two hashes in ruby

I have two collections of hashes

and_filters = [{:filter=>:brand, :value=>"Fila"}, {:filter=>:brand, :value=>"Adidas"}]
or_filters = [{:filter=>:gender, :value=>"Hombre"}]

and i need make like the following struct

:_or => [
  { :_and => [
    {:gender => "Hombre"}, 
    {:brand => "Adidas"}] 
  }, 
  { :_and => [
    {:gender=>"Hombre"}, 
    {:brand=>"Fila"}] 
  }
]

For this i did

query[:_or] = []
or_filters.each do |or_f|
  query[:_or] << {
    :_and => [
      and_filters.map do |and_f|
        {and_f[:filter] => and_f[:value]}
      end
      { or_f[:filter] => or_f[:value] }
    ]
  }
end

but an error Expected: { shows in code. Apparently the second loop is badly syntactically

It's not pretty, but I believe this gives the desired results:

{_or: or_filters.each_with_object([]) do |or_filter, or_filter_ary|
    or_filter_hsh = {or_filter[:filter] => or_filter[:value]}
    and_filters.each do |and_filter|
      and_filter_hsh = {and_filter[:filter] => and_filter[:value]}
      or_filter_ary << {_and: [or_filter_hsh, and_filter_hsh]}
    end
  end
}

Which gives:

{:_or => [
  { :_and => [
    {:gender=>"Hombre"}, 
    {:brand=>"Fila"}
  ]}, 
  { :_and => [
    {:gender=>"Hombre"}, 
    {:brand=>"Adidas"}
  ]}
]}

It looks like you want every combination of the given and_filters with the given or_filters . In that case, and assuming you don't care about order ( :gender before :brand vs. the other way around) Array#product is your friend:

result = {
  _or: and_filters.product(or_filters).map do |a|
    { _and: a.map {|filter:, value:| { filter => value }} }
  end
}
# => {
#      :_or => [
#        {:_and => [{:brand=>"Fila"}, {:gender=>"Hombre"}]},
#        {:_and => [{:brand=>"Adidas"}, {:gender => "Hombre"}]}
#      ]
#    }

See it in action on repl.it: https://repl.it/@jrunning/HorizontalDirectCharmap

Thats what i was looking for

query = {}
query[:_or] = or_filters.map do |or_f|
  and_filters_aux = and_filters.dup
  and_filters_aux << or_f
  { :_and => and_filters_aux.map{|hsh| {hsh[:filter] => hsh[:value]} } }
end

https://repl.it/repls/ShyLateClients

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM