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

У меня есть такой массив:

result = [
  {:label=>:road, :value=>"carl-schurz str."},
  {:label=>:house_number, :value=>"25"},
  {:label=>:postcode, :value=>"36041"},
  {:label=>:city, :value=>"fulda"},
  {:label=>:state_district, :value=>"fulda kreis"}
] 

Я хотел бы вернуть хеш, как показано ниже:

output = {
  "road" => "carl-schurz str.",
  "house_number" => "25",
  "postcode" => "36041",
  "city" => "fulda",
  "state_district" => "fulda kreis"
}

Поскольку я знаю, что хэши также могут иметь позиции, яЯ пробовал что-то вроде:

result.each do |r|
    r.each do |key, value|
      output[value[0]] = value[1]
    end
   end 

Но я не получаю правильных результатов ..

Ответы [ 5 ]

0 голосов
/ 25 августа 2018

Еще один способ:

result.map.with_object({}) { |h, new_h| new_h[h[:label]] = h[:value] }
0 голосов
/ 25 августа 2018
result.map { |h| h.values_at(:label, :value) }.to_h
  #=> {:road=>"carl-schurz str.", :house_number=>"25", :postcode=>"36041", 
  #    :city=>"fulda", :state_district=>"fulda kreis"}
0 голосов
/ 25 августа 2018

Просто добавив некоторые другие решения к вашему сведению.

Лично я бы сделал что-то вроде этого:

Hash[result.map { |h| [h[:label], h[:value]] }]

Еще одна вещь, на которую вы можете обратить внимание: each_with_object, которая может быть очень удобной для создания новых объектов. В этом случае это будет выглядеть примерно так:

new_hash = result.each_with_object({}) do |h, r|
  r[h[:label]] = h[:value]
end
0 голосов
/ 25 августа 2018

Вы можете сделать это легко с "картой" ...

result.map { |h| [h[:label], h[:value]] }.to_h
Hash[result.map { |h| [h[:label], h[:value]] }]

... или даже "уменьшить" ...

result.reduce(Hash.new) { |h,o| h[o[:label]] = o[:value]; h }

Этот простой тест показывает, что форма "уменьшить" немного быстрее, чем другие:

require 'benchmark'

result = [
  {:label=>:road, :value=>"carl-schurz str."},
  {:label=>:house_number, :value=>"25"},
  {:label=>:postcode, :value=>"36041"},
  {:label=>:city, :value=>"fulda"},
  {:label=>:state_district, :value=>"fulda kreis"}
] 

n = 1_000_000

Benchmark.bmbm do |x|
  x.report('Hash[]    ') { n.times { Hash[result.map { |h| [h[:label], h[:value]] }] } }
  x.report('map...to_h') { n.times { result.map { |h| [h[:label], h[:value]] }.to_h } }
  x.report('reduce    ') { n.times { result.reduce(Hash.new) { |h,o| h[o[:label]] = o[:value]; h } } }
end

#                  user     system      total        real
# Hash[]       1.830000   0.040000   1.870000 (  1.882664)
# map...to_h   1.760000   0.040000   1.800000 (  1.810998)
# reduce       1.590000   0.030000   1.620000 (  1.633808) *
0 голосов
/ 25 августа 2018

Мне удалось получить желаемый результат, используя это:

result.each do |r|
  output[r.values[0]] = values[1]
end

Ключом было знание об использовании hash_object.values.

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