Ruby - печатать только значения дублированных ключей хеша в массиве хэшей - PullRequest
0 голосов
/ 01 июля 2018

Я создал массив хешей из данных 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 голосов
/ 02 июля 2018

Предполагая, что у вас есть переменная 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"]}
0 голосов
/ 01 июля 2018

Это даст вам общие значения:

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

И их вы можете напечатать так, как вам нравится. Не знаю, хотите ли вы напечатать ключи, значения или оба, но как вам нравится:

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

Очевидно, что вы можете объединить эти два фрагмента в одну команду, но для ясности они равны 2.

EDIT: Просто заметил, что вы хотели в качестве массива. Если вы хотели только значения:

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' неправильно? это правильно?

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...