Ruby: самый быстрый путь от хэша A к хешу B - PullRequest
1 голос
/ 02 ноября 2011

Я новичок в ruby ​​и ищу элегантный способ сортировки следующего хэша.

Хэш A:

a = { :metric1 => {
          "Bob" =>10,
          "Jane" =>15,
          "Sally" =>20
      },                
      :metric2 => {  
          "Jane" =>15,
          "Bob" =>10,
          "Sally" =>10 
      },         
      :metric3 => {  
          "Bob" =>10,
          "Sally" =>10,
          "Jane" =>5
      }
    }

Хэш B:

b = { "Bob" => {
        :metric1 =>10,
        :metric2 =>10,
        :metric3 =>10
      },
      "Jane" => {
        :metric1 =>15,
        :metric2 =>15,
        :metric3 =>5
      },
      "Sally" => {
        :metric1 =>20,
        :metric2 =>10,
        :metric3 =>10
      }
    }

По сути, я хочу простой способ итерации этого объекта для вывода таблицы вроде:

        Metric 1  Metric 2  Metric 3
Bob     10        20        20
Jane    15        15        5
Sally   20        10        10

Ответы [ 3 ]

3 голосов
/ 02 ноября 2011

Функциональный подход (предполагается, что все люди имеют одинаковые метрические ключи):

names = a.values.first.keys
b = Hash[names.map do |name| 
  [name, Hash[a.map { |metric, values| [metric, values[person]] }]]
end]

[Править] Второй подход, вероятно, более ортодоксальный, чем моя первая попытка.Он использует Facets (поэтому он может показаться немного загадочным для тех, кто не знаком с новыми абстракциями, которые он предлагает).Тем не менее, это легко, если вы проверяете вывод каждого шага:

triplets = a.flat_map { |metric, h| h.map { |name, value| [name, metric, value] } }
pairs_by_name = triplets.map_by { |name, metric, value| [name, [metric, value]] }
b = pairs_by_name.mash { |name, pairs| [name, pairs.to_h] }
2 голосов
/ 02 ноября 2011

Я бы более просто сделал:

h = {}
a.each do |metric, hash|
  hash.each do |name, value|
    h[name] ||= {}
    h[name][metric] = value
  end
end
0 голосов
/ 02 ноября 2011

Вот ответ с более функциональным вкусом.Он обрабатывает случай, когда некоторые имена встречаются только в некоторых хешах - скажем, Sally only присутствовал только для: metric3 - хотя и помещая nils в результирующий хеш

metrics = a.keys
names = a.values.map { |v| v.keys }.flatten.uniq

names.inject({}) do |memo, name|
  memo[name] = metrics.inject({}) do |memo, metric|
    memo[metric] = a[metric][name]
    memo
  end
  memo
end
Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...