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

时间:2018-07-01 08:24:58

标签: arrays ruby xml parsing hash

我从数据ive创建了一个哈希数组,以从一个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

2 个答案:

答案 0 :(得分:0)

这将为您提供共享的值:

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”?正确吗?

答案 1 :(得分:0)

假设您有一个变量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"]}