【问题标题】:How to merge multiple hashes?如何合并多个哈希?
【发布时间】:2013-08-20 07:49:15
【问题描述】:

现在,我正在合并两个这样的哈希:

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=>{"免费超级保护 运费"=>126649}}

但现在我想在未来合并更多。例如:

department_hash  = self.parse_department html
super_saver_hash = self.parse_super_saver html
categories_hash  = self.parse_categories html

如何合并多个哈希?

【问题讨论】:

  • +1 好问题..

标签: ruby hash


【解决方案1】:

怎么样:

[department_hash, super_saver_hash, categories_hash].reduce &:merge

【讨论】:

  • 为什么是&[department_hash, super_saver_hash, categories_hash].reduce(:merge) 很好...
  • 这只是我的偏好。我认为& 提供了一些信息并且是值得的。
  • @Babai 因为这种风格与例如Enumerable#map 需要一个过程。
【解决方案2】:

您可以再次拨打merge

h1 = {foo: :bar}
h2 = {baz: :qux}
h3 = {quux: :garply}

h1.merge(h2).merge(h3)
#=> {:foo=>:bar, :baz=>:qux, :quux=>:garply}

【讨论】:

  • 我认为关键是如何通过一个电话来做到这一点。 h1.merge(h2, h3) 显然这实际上不起作用,但这种行为可能很有用。
  • 这就是我要找的东西
【解决方案3】:

您可以使用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"}

【讨论】:

    【解决方案4】:

    在完成了这个问题及其答案之后,我花了一段时间才弄清楚如何合并多嵌套哈希。结果发现我错误地遍历了哈希集合,导致null 值出现各种问题。

    这个sample 命令行应用程序展示了如何使用storemerge! 的组合合并多个哈希,具体取决于它们是否是顶级哈希键。它使用带有一些已知键名的命令行参数进行分类。

    下面提供了 Gist URL 的完整代码:

    # 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
    

    【讨论】:

      【解决方案5】:

      假设你有arr = [{x: 10},{y: 20},{z: 30}] 然后做

      arr.reduce(:merge)
      

      【讨论】:

        猜你喜欢
        • 2013-10-18
        • 1970-01-01
        • 1970-01-01
        • 2023-02-06
        • 2016-09-02
        • 2012-01-14
        • 2020-09-25
        • 2017-09-26
        • 1970-01-01
        相关资源
        最近更新 更多