Соедините значения двух хешей - PullRequest
0 голосов
/ 12 марта 2019

У меня вопрос, как я могу объединить содержимое двух хешей, например

[
  {:user=>"Maria", :alerts=>{:rfc=>"This rfc is invalid"}},
  {:user=>"Juan", :alerts=>{:email=>"This email is invalid"}}
]

[
  {:user=>"Maria", :alerts=>{:income_in_the_mean=>true, :credit_in_the_mean=>true}},
  {:user=>"Juan", :alerts=>{:income_in_the_mean=>false, :credit_in_the_mean=>true}}
]

и получите одно единственное значение для оповещения у каждого пользователя

[
  {:user=>"Maria", :alerts=>{:rfc=>"This rfc is invalid", :income_in_the_mean=>true, :credit_in_the_mean=>true}},
  {:user=>"Juan", :alerts=>{:email=>"This email is invalid",:income_in_the_mean=>false, :credit_in_the_mean=>true}}
]

Ответы [ 4 ]

2 голосов
/ 12 марта 2019

Если вы используете Ruby on Rails, вы можете сделать что-то вроде этого:

h1 = [
  {:user=>"Maria", :alerts=>{:rfc=>"This rfc is invalid"}},
  {:user=>"Juan", :alerts=>{:email=>"This email is invalid"}}
]

h2 = [
  {:user=>"Maria", :alerts=>{:income_in_the_mean=>true, :credit_in_the_mean=>true}},
  {:user=>"Juan", :alerts=>{:income_in_the_mean=>false, :credit_in_the_mean=>true}}
]

(h1+h2).group_by{|h| h[:user]}.values.map{|v| v.reduce(:deep_merge)}

Вывод:

[
  {:user=>"Maria", :alerts=>{:rfc=>"This rfc is invalid", :income_in_the_mean=>true, :credit_in_the_mean=>true}},
  {:user=>"Juan", :alerts=>{:email=>"This email is invalid", :income_in_the_mean=>false, :credit_in_the_mean=>true}}
]

Имейте в виду, что это будет работать, только если у вас есть ровно два хеша для каждого пользователя.

Я обновил свой ответ благодаря @tadman и @ 3limin4t0r

1 голос
/ 12 марта 2019

Просто из любопытства, старое доброе рубиновое решение:

[h1 + h2].each_with_object(Hash.new { |h, k| h[k] = {} }) do |h, acc|
  acc[h[:user]].merge!(h) { |_, v1, v2| v1.merge(v2) rescue v1 }
end.values
0 голосов
/ 12 марта 2019

Это чисто Ruby решение.

arr = [
  [
    {:user=>"Maria",
     :alerts=>{:rfc=>"This rfc is invalid"}},
    {:user=>"Juan",
     :alerts=>{:email=>"This email is invalid"}}
  ],
  [
    {:user=>"Maria",
       :alerts=>{:income_in_the_mean=>true, :credit_in_the_mean=>true}},
    {:user=>"Juan",
       :alerts=>{:income_in_the_mean=>false, :credit_in_the_mean=>true}}
  ]
]

arr.flatten.group_by { |h| h[:user] }.map do |user,a|
  { user: user, alerts: a.reduce({}) { |h,g| h.merge(g[:alerts]) } }
end
  #=> [{:user=>"Maria",
  #     :alerts=>{:rfc=>"This rfc is invalid", :income_in_the_mean=>true,
  #               :credit_in_the_mean=>true}},
  #    {:user=>"Juan",
  #     :alerts=>{:email=>"This email is invalid", :income_in_the_mean=>false,
  #               :credit_in_the_mean=>true}}] 

Примечание:

arr.flatten.group_by { |h| h[:user] }
  #=> {"Maria"=>[{:user=>"Maria", :alerts=>{:rfc=>"This rfc is invalid"}},
  #              {:user=>"Maria", :alerts=>{:income_in_the_mean=>true,
  #                 :credit_in_the_mean=>true}}],
  #    "Juan" =>[{:user=>"Juan", :alerts=>{:email=>"This email is invalid"}},
  #              {:user=>"Juan", :alerts=>{:income_in_the_mean=>false,
  #                 :credit_in_the_mean=>true}}]} 

arr банкаконечно, любого размера.

0 голосов
/ 12 марта 2019

Простой подход на основе индекса может выглядеть примерно так:

array_1 = [
  {:user=>"Maria", :alerts=>{:rfc=>"This rfc is invalid"}},
  {:user=>"Juan", :alerts=>{:email=>"This email is invalid"}}
]

array_2 = [
  {:user=>"Maria", :alerts=>{:income_in_the_mean=>true, :credit_in_the_mean=>true}},
  {:user=>"Juan", :alerts=>{:income_in_the_mean=>false, :credit_in_the_mean=>true}}
]

array_1.zip(array_2).map { |item_1, item_2| item_1.deep_merge(item_2) }
#=> [
#   {:user=>"Maria", :alerts=>{:rfc=>"This rfc is invalid", :income_in_the_mean=>true, :credit_in_the_mean=>true}},
#   {:user=>"Juan", :alerts=>{:email=>"This email is invalid", :income_in_the_mean=>false, :credit_in_the_mean=>true}}
# ]

Использование Array#zip и Rails #deep_merge. Чтобы это работало, массивы должны быть одинакового размера, а элементы для объединения должны находиться в одной позиции индекса.

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...