如何在ruby中使用hash?

时间:2017-04-06 09:37:27

标签: ruby

我的哈希示例:

{"79_6"=>"0", "85_6"=>"1", "86_6"=>"1", "79_8638"=>"0", "80_8638"=>"0", "81_8638"=>"0", "82_8638"=>"1", "83_8638"=>"1", "84_8638"=>"0", "85_8638"=>"1", "86_8638"=>"0", "79_8639"=>"0", "80_8639"=>"0", "81_8639"=>"0", "82_8639"=>"0", "83_8639"=>"0", "84_8639"=>"0", "85_8639"=>"0", "86_8639"=>"0", "80_8640"=>"0", "81_8640"=>"1", "82_8640"=>"1", "83_8640"=>"1", "84_8640"=>"0", "85_8640"=>"0", "86_8640"=>"0"}

我需要获取密钥为1的参数:

["85_6", "86_6", "82_8638", "83_8638", "85_8638", "81_8640", "82_8640", "83_8640"]

接下来,我需要分组:

{"6"=>"85, 86", "8638"=> "83, 82, 85", "8640" => "81, 82, 83"}

4 个答案:

答案 0 :(得分:3)

hash.select { |_, v| v == '1' }
    .keys
    .map { |e| e.split('_') }
    .group_by(&:pop)
    .map { |k, v| [k, v.join(', ')] }
    .to_h
#⇒ {
#     "6" => "85, 86",
#  "8638" => "82, 83, 85",
#  "8640" => "81, 82, 83"
# }

答案 1 :(得分:2)

另一个解决方案(只需1次迭代):

h.each_with_object(Hash.new {|h, k| h[k] = ''}) do |(k, v), m| 
  f, s = k.split('_')
  m[s] << (m[s].empty? ? f : ", #{f}") if v == '1'
end
#=> {"6"=>"85, 86", "8638"=>"82, 83, 85", "8640"=>"81, 82, 83"}

答案 2 :(得分:1)

是的,我知道这是一堆废话,但是因为浪费了15分钟而在这里张贴 - ))

a = {"79_6"=>"0", "85_6"=>"1", "86_6"=>"1", "79_8638"=>"0", "80_8638"=>"0", "81_8638"=>"0", "82_8638"=>"1", "83_8638"=>"1", "84_8638"=>"0", "85_8638"=>"1", "86_8638"=>"0", "79_8639"=>"0", "80_8639"=>"0", "81_8639"=>"0", "82_8639"=>"0", "83_8639"=>"0", "84_8639"=>"0", "85_8639"=>"0", "86_8639"=>"0", "80_8640"=>"0", "81_8640"=>"1", "82_8640"=>"1", "83_8640"=>"1", "84_8640"=>"0", "85_8640"=>"0", "86_8640"=>"0"}

a.select {|k| a[k] == '1' }
  .keys.map {|e| e.split('_')}
  .map(&:reverse)
  .group_by(&:first)
  .map{|k,v| [k, v.flatten.join(",")] }
  .gsub("#{k},", " ")] }.to_h

答案 3 :(得分:0)

hash = {"79_6"=>"0", "85_6"=>"1", "86_6"=>"1", "79_8638"=>"0", "80_8638"=>"0", "81_8638"=>"0", "82_8638"=>"1", "83_8638"=>"1", "84_8638"=>"0", "85_8638"=>"1", "86_8638"=>"0", "79_8639"=>"0", "80_8639"=>"0", "81_8639"=>"0", "82_8639"=>"0", "83_8639"=>"0", "84_8639"=>"0", "85_8639"=>"0", "86_8639"=>"0", "80_8640"=>"0", "81_8640"=>"1", "82_8640"=>"1", "83_8640"=>"1", "84_8640"=>"0", "85_8640"=>"0", "86_8640"=>"0"}

new_hash = hash.keep_if {|k,v| v == "1"} # keep only value == "1"

     .map{|a|a.first.gsub("_",",").split(",")} # clean data

     .group_by(&:pop) # group data by the last value which become the key

new_hash.map{|k,v| [k, v.join(',')]}.to_h #transform array of values in string and array to hash

希望它有所帮助,不要苛刻它是我在StackOver上的第一个答案;)