Ruby - 仅打印哈希数组中重复哈希键的值



>我已经从数据中创建了一个哈希数组,以便从xml文件中提取。问题是,数组中的某些哈希键是重复的,并且 id 喜欢只提取值。 例如,下面的代码输出以下内容:

{"server_host"=>"hostone", "server_type"=>"redhat", "server_name"=>"RedhatOne"}
{"server_host"=>"hostone", "server_type"=>"windows", "server_name"=>"WinOne"} 

我希望能够打印出这个:

{"server_host"=>"hostone", "server_type"=>"redhat", "server_name"=>"RedhatOne"}
"server_type"=>"windows", "server_name"=>"WinOne"}

我想我需要基于重复键创建另一个数组,但我在下面尝试的不起作用:

def parse_xml_file(filename)
require 'nokogiri'
xmlSource = File.read(filename)
parsedXml = Nokogiri::XML(xmlSource)
hostArray = Array.new
parsedXml.xpath("/New/Server").each do |srvNode|
hostNode = srvNode.at_xpath("Host")
hostArray << {"server_name"=>srvNode["Name"], 
"server_type"=>srvNode["Type"], "server_host"=>hostNode["Address"] } 
grouped = hostArray.group_by{|row| [row[:server_host]]}
filtered = grouped.values.select { |a| a.size > 1 }.flatten
end

假设你有一个包含重复哈希的变量hash_arr,这里有一些代码应该让你非常接近你想要的地方。它没有优化,但很容易理解:

hash_arr.group_by { |h| h["server_host"] }.each do |host_name, values|
puts "Server Host: #{host_name}"
values.each do |val|
val.delete("server_host")
puts val
end
end

打印输出:

Server Host: hostone
{"server_type"=>"redhat", "server_name"=>"RedhatOne"}
{"server_type"=>"windows", "server_name"=>"WinOne"}

或者,如果您只是每个组的值而不跨哈希关联它们:

hash_arr =[{"server_host"=>"hostone", "server_type"=>"redhat", "server_name"=>"RedhatOne"}, {"server_host"=>"hostone", "server_type"=>"windows", "server_name"=>"WinOne"}]
merged_hash = {}
hash_arr.each do |hash|
hash.each do |k, v|
merged_hash[k] ||= []
merged_hash[k] << v
end
end
merged_hash.values.each(&:uniq!)

然后输出:

[9] pry(main)> merged_hash
=> {"server_host"=>["hostone"], "server_type"=>["redhat", "windows"], "server_name"=>["RedhatOne", "WinOne"]}

这将为你提供共享值:

shared = hash1.keep_if { |k, v| hash2.key? k }

您可以随心所欲地打印它们。不知道是要打印键、值还是两者,但随心所欲

shared.each_pair { |k, v| print k, v }

您显然可以将这两个代码片段合并为一个命令,但为了清楚起见,它们是 2。

编辑:刚刚注意到你想要作为一个数组。如果您只想要值:

array = hash1.keep_if { |k, v| hash2.key? k }.values

感谢您的建议 - 我试过这个:

shared = Hash.new
grouped = hostArray.group_by{|row| [row[:server_host]]}
filtered = grouped.values.select { |a| a.size > 1 }.flatten
filtered.each do |element|
element.each do |key, value|
shared = element.keep_if { |k, v| element.key? k }
end
shared.each_pair { |k, v| print k," ", v, "n" }

结束

但是这个输出仍然不正确 - 我想我错误地引用了"hash2"? 这是对的吗?

最新更新