【问题标题】:Nesting a Ruby hash嵌套 Ruby 哈希
【发布时间】:2017-08-07 20:53:55
【问题描述】:

我有一个方法可以像这样从我的表中选择所有行:

smtp_status_raw = my_table.select(:message, :is_valid, :hostname).map { |h| h.values }

这会返回一个像这样的数组:

[{:message=>"blah", :is_valid=>true, :hostname=>"1"}, {:message=>"blah", :is_valid=>true, :hostname=>"2"}, {:message=>"blah", :is_valid=>true, :hostname=>"3}]

使用上述信息,我想创建一个如下所示的哈希:

{ 
:node_status => 
    {
        {:hostname => "1", :message: "blah"},
        {:hostname => "2", :message: "blah"},
        {:hostname => "3", :message: "blah"}
    }
}

首先,我的问题是 - 是否可以创建像上面这样的哈希?在上面的 Sequel 查询示例中,我有三个对象,它们是三个独立的主机,我想将这三个主机添加到 :node_status 键中。那可能吗?如果那不是有效的哈希,还有什么替代方法?

其次,这是我尝试过的:

# Initialize the hash
smtp_status_hash = { :node_status: => nil }

我已经用 node_status 键初始化了 smtp_status_hash 哈希,但我不确定如何嵌套查询结果..

【问题讨论】:

    标签: ruby hash sequel


    【解决方案1】:

    这不是一个有效的哈希,因为您有 3 个值,但 :node_status 子哈希中没有键。你可以这样做:

    smtp_status_raw = [
      {:message=>"blah", :is_valid=>true, :hostname=>"1"},
      {:message=>"blah", :is_valid=>true, :hostname=>"2"},
      {:message=>"blah", :is_valid=>true, :hostname=>"3"}
    ]
    
    {
      node_status: smtp_status_raw.collect do |hash|
        hash.reject { |key, value| key == :is_valid }
      end
    }
    

    :node_status 中的值作为数组获取:

    {
      :node_status=>[
        {:message=>"blah", :hostname=>"1"},
        {:message=>"blah", :hostname=>"2"},
        {:message=>"blah", :hostname=>"3"}
      ]
    }
    

    或者你可以这样做:

    {
      node_status: smtp_status_raw.collect do |hash|
        [hash[:hostname], hash[:message]]
      end.to_h
    }
    

    它设置了一个子哈希,key:hostnamevalue:message

    {
      :node_status=>{
        "1"=>"blah",
        "2"=>"blah",
        "3"=>"blah"
      }
    }
    

    或者如果您有更多想要保留的钥匙:

    {
      node_status: smtp_status_raw.collect do |hash|
        [hash[:hostname], hash.reject { |key, value| key == :is_valid }]
      end.to_h
    }
    

    这仍然是一个哈希,其中 key:hostnamevalue 有另一个哈希:

    {
      :node_status=>{
        "1"=>{:message=>"blah", :hostname=>"1"},
        "2"=>{:message=>"blah", :hostname=>"2"},
        "3"=>{:message=>"blah", :hostname=>"3"}
      }
    }
    

    要在创建 Hash 后设置键的值,您可以执行以下操作:

    smtp_status_hash = { node_status:  nil }
    smtp_status_hash[:node_status] = "Whatever you want here"
    

    您可以阅读有关Hash 及其方法的更多信息,以及如何通过selectreject 从散列中保留或删除密钥。哈希虽然是一个字典结构,但必须始终有一个 key 和一个 value,尽管该值可能是一个 Array 或另一个 Hash

    【讨论】:

    • 嘿简单。您能解释一下我的问题中我的“所需”哈希与您示例中的第一个哈希之间的区别吗?好像你把它变成了一个数组吧?
    • 是的,它只是一个嵌套在:node_status 中的数组,而不是一个散列。所以你想要的哈希不是有效哈希的唯一原因是因为你有:node_status => {...}而不是:node_status => [...],这会告诉Ruby你想要每个节点的键/值对,而不仅仅是一个列表它们,并且只给出值(或者,只给出没有值的键)
    【解决方案2】:

    试试这个

    smtp_status_hash = {:node_status=>[]}; my_table.select(:message, :is_valid, :hostname).map{ |h| h.values }.each{|i| smtp_status_hash[:node_status] << (i)}

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 1970-01-01
      • 2019-02-21
      • 2019-08-08
      • 2021-02-03
      • 1970-01-01
      • 2018-04-24
      • 1970-01-01
      相关资源
      最近更新 更多