嵌套一个Ruby哈希表

5
我有一个选择表格所有行的方法,如下所示:

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哈希表,但我不确定如何嵌套查询结果。

2个回答

6

这不是一个有效的哈希值,因为你有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:hostname,但value有另一个哈希表:

{
  :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及其方法的更多信息,以及如何使用 select reject 从哈希中保留或删除键。哈希是一个字典结构,必须始终具有一个key和单个value,尽管该值可以是Array或另一个Hash

嘿Simple,你能解释一下我在问题中所提到的“期望”哈希和你示例中的第一个哈希之间的区别吗?看起来你把它转换成了一个数组,是吗? - theGreenCabbage
1
是的,它只是一个嵌套在:node_status中的数组,而不是哈希表。因此,你期望的哈希表无效的唯一原因是你使用了 :node_status => {...} 而不是 :node_status => [...],这会告诉 Ruby 你想要每个节点的键值对,而不仅仅是它们的列表,并且只提供值(或者只提供没有值的键)。 - Simple Lime

0

试一下这个

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


网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接