Ответ 1
Вы можете сделать это ниже, используя Enumerable#inject
:
h = {}
arr = [{:a=>"b"},{"c" => 2},{:a=>4,"c"=>"Hi"}]
arr.inject(h,:update)
# => {:a=>4, "c"=>"Hi"}
arr.inject(:update)
# => {:a=>4, "c"=>"Hi"}
Прямо сейчас, я объединяю два хэша следующим образом:
department_hash = self.parse_department html
super_saver_hash = self.parse_super_saver html
final_hash = department_hash.merge(super_saver_hash)
Вывод:
{: department = > { "Принадлежности для домашних животных" = > { "Птицы" = > 16281, "Кошки" = > 245512, "Собаки" = > 513926, "Рыбы и водные животные" = > 46811, "Лошади" = > 14805, "Насекомые" = > 364, "Рептилии и амфибии" = > 5816, "Маленькие Животные" = > 19769}},: super_saver = > { "Free Super Saver Доставка" = > 126649}}
Но теперь я хочу объединить больше в будущем. Например:
department_hash = self.parse_department html
super_saver_hash = self.parse_super_saver html
categories_hash = self.parse_categories html
Как слить несколько хэшей?
Вы можете сделать это ниже, используя Enumerable#inject
:
h = {}
arr = [{:a=>"b"},{"c" => 2},{:a=>4,"c"=>"Hi"}]
arr.inject(h,:update)
# => {:a=>4, "c"=>"Hi"}
arr.inject(:update)
# => {:a=>4, "c"=>"Hi"}
Как насчет:
[department_hash, super_saver_hash, categories_hash].reduce &:merge
Вы можете просто вызвать merge
еще раз:
h1 = {foo: :bar}
h2 = {baz: :qux}
h3 = {quux: :garply}
h1.merge(h2).merge(h3)
#=> {:foo=>:bar, :baz=>:qux, :quux=>:garply}
Мне потребовалось некоторое время, чтобы выяснить, как объединить многозадачные хэши после прохождения этого Вопроса и его ответов. Оказалось, что я неправильно повторяю коллекции хэшей, вызывая все проблемы с значениями null
.
Это пример приложение командной строки показывает, как объединить несколько хэшей с комбинацией store
и merge!
, в зависимости от того, будет ли или они не были хеш-ключами верхнего уровня. Он использует аргументы командной строки с несколькими известными ключевыми именами для целей категоризации.
Полный код из URL-адреса Gist представлен ниже в качестве любезности:
# Ruby - A nested hash example
# Load each pair of args on the command-line as a key-value pair
# For example from CMD.exe:
# call ruby.exe ruby_nested_hash_example.rb Age 30 Name Mary Fav_Hobby Ataraxia Fav_Number 42
# Output would be:
# {
# "data_info": {
# "types": {
# "nums": {
# "Age": 30,
# "Fav_Number": 42
# },
# "strings": {
# "Name": "Mary",
# "Fav_Hobby": "Ataraxia"
# }
# },
# "data_id": "13435436457"
# }
# }
if (ARGV.count % 2 != 0) || (ARGV.count < 2)
STDERR.puts "You must provide an even amount of command-line args to make key-value pairs.\n"
abort
end
require 'json'
cmd_hashes = {}
nums = {}
strings = {}
types = {}
#FYI `tl` == top-level
all_tl_keys = {}
data_info = {}
data_id = {:data_id => "13435436457"}
_key = ""
_value = ""
element = 0
ARGV.each do |i|
if element % 2 == 0
_key=i
else
if (i.to_i!=0) && (i!=0)
_value=i.to_i
else
_value=i
end
end
if (_key != "") && (_value != "")
cmd_hashes.store(_key, _value)
_key = ""
_value = ""
end
element+=1
end
cmd_hashes.each do |key, value|
if value.is_a? Numeric
nums.store(key, value)
else
strings.store(key, value)
end
end
if nums.size > 0; types.merge!(:nums => nums) end
if strings.size > 0; types.merge!(:strings => strings) end
if types.size > 0; all_tl_keys.merge!(:types => types) end
if data_id.size > 0; all_tl_keys.merge!(data_id) end
if all_tl_keys.size > 0; data_info.merge!(:data_info => all_tl_keys) end
if data_info.size > 0; puts JSON.pretty_generate(data_info) end