Ruby-从哈希数组中创建哈希

时间:2014-05-16 23:00:54

标签: ruby arrays ruby-on-rails-4 hash

我有一系列哈希:

@operating_systems = [
  {"title"=>"iPhone", "value_percent"=>"42.6"},
  {"title"=>"Windows 7", "value_percent"=>"21.3"},
  {"title"=>"Android", "value_percent"=>"12.8"},
  {"title"=>"Mac OS X", "value_percent"=>"8.5"},
  {"title"=>"Windows 8.1", "value_percent"=>"6.4"},
  {"title"=>"Windows XP", "value_percent"=>"4.3"},
  {"title"=>"Linux", "value_percent"=>"2.1"},
  {"title"=>"Windows Vista", "value_percent"=>"2.1"}
] 

并想要创建以下哈希:

 {"iphone" => "42.6", "windows 7" => "21.3", ... "windows vista" => "2.1"}

实现这一目标的最佳方法是什么?

5 个答案:

答案 0 :(得分:6)

[
  {"title"=>"iPhone", "value_percent"=>"42.6"},
  {"title"=>"Windows 7", "value_percent"=>"21.3"},
  {"title"=>"Android", "value_percent"=>"12.8"},
  {"title"=>"Mac OS X", "value_percent"=>"8.5"},
  {"title"=>"Windows 8.1", "value_percent"=>"6.4"},
  {"title"=>"Windows XP", "value_percent"=>"4.3"},
  {"title"=>"Linux", "value_percent"=>"2.1"},
  {"title"=>"Windows Vista", "value_percent"=>"2.1"}
]
.map{|h| h.values.map(&:downcase)}.to_h
# =>
# {
#   "iphone"=>"42.6",
#   "windows 7"=>"21.3",
#   "android"=>"12.8",
#   "mac os x"=>"8.5",
#   "windows 8.1"=>"6.4",
#   "windows xp"=>"4.3",
#   "linux"=>"2.1",
#   "windows vista"=>"2.1"
# }

答案 1 :(得分:2)

这是单程

 op_sys =  [{"title"=>"iPhone", "value_percent"=>"42.6"}, {"title"=>"Windows 7", "value_percent"=>"21.3"}, {"title"=>"Android", "value_percent"=>"12.8"}, {"title"=>"Mac OS X", "value_percent"=>"8.5"}, {"title"=>"Windows 8.1", "value_percent"=>"6.4"}, {"title"=>"Windows XP", "value_percent"=>"4.3"}, {"title"=>"Linux", "value_percent"=>"2.1"}, {"title"=>"Windows Vista", "value_percent"=>"2.1"}] 

    new_hash = op_sys.inject({}) {|r,e| r[e['title']] = e['value_percent']; r}

    p new_hash

修改

您可能希望新的哈希键处于小写状态......所以可以选择:

new_hash = op_sys.inject({}) {|r,e| r[e['title'].downcase] = e['value_percent']; r}

答案 2 :(得分:1)

@Sawa最接近我的目标:

operating_systems = [
  {"title"=>"iPhone", "value_percent"=>"42.6"},
  {"title"=>"Windows 7", "value_percent"=>"21.3"},
  {"title"=>"Android", "value_percent"=>"12.8"},
  {"title"=>"Mac OS X", "value_percent"=>"8.5"},
  {"title"=>"Windows 8.1", "value_percent"=>"6.4"},
  {"title"=>"Windows XP", "value_percent"=>"4.3"},
  {"title"=>"Linux", "value_percent"=>"2.1"},
  {"title"=>"Windows Vista", "value_percent"=>"2.1"}
] 
operating_systems.map(&:values).to_h 
# => {"iPhone"=>"42.6",
#     "Windows 7"=>"21.3",
#     "Android"=>"12.8",
#     "Mac OS X"=>"8.5",
#     "Windows 8.1"=>"6.4",
#     "Windows XP"=>"4.3",
#     "Linux"=>"2.1",
#     "Windows Vista"=>"2.1"}

适用于Ruby 2.1 +。

或者,在旧版本的Ruby上:

Hash[operating_systems.map(&:values)] 
# => {"iPhone"=>"42.6",
#     "Windows 7"=>"21.3",
#     "Android"=>"12.8",
#     "Mac OS X"=>"8.5",
#     "Windows 8.1"=>"6.4",
#     "Windows XP"=>"4.3",
#     "Linux"=>"2.1",
#     "Windows Vista"=>"2.1"}

如果需要将键折叠为小写,请使用以下命令替换上述命令:

operating_systems.map{ |h| k, v = h.values; [k.downcase, v] }.to_h
# => {"iphone"=>"42.6",
#     "windows 7"=>"21.3",
#     "android"=>"12.8",
#     "mac os x"=>"8.5",
#     "windows 8.1"=>"6.4",
#     "windows xp"=>"4.3",
#     "linux"=>"2.1",
#     "windows vista"=>"2.1"}

Hash[operating_systems.map{ |h| k, v = h.values; [k.downcase, v] }]
# => {"iphone"=>"42.6",
#     "windows 7"=>"21.3",
#     "android"=>"12.8",
#     "mac os x"=>"8.5",
#     "windows 8.1"=>"6.4",
#     "windows xp"=>"4.3",
#     "linux"=>"2.1",
#     "windows vista"=>"2.1"}

答案 3 :(得分:0)

虽然有许多更聪明的方法,但通过修改输出散列对源数组进行简单循环就足够了;考虑

arr = [{"title"=>"iPhone", "value_percent"=>"42.6"}, ..]

hash = {}
arr.each do |item|
   key = item["title"]
   value = item["value_percent"]
   hash[key] = value
end   

并查看ideone demo。这是一项非常简单的任务,我希望它的解决方法如上所述 - 在“工作”之前没有“最佳”。


一旦理解了基本方法,就可以完成相同的过程(转换然后从成对构建地图)

hash = Hash[arr.map do |v| [v["title"], v["value_percent"]] end]

这“更好”吗? 耸肩,我猜它“更短”并且仍然清晰..(并且可以轻易地添加任何其他转换)

答案 4 :(得分:0)

Enumerable#reduceHash#merge

结合使用
op_sys.reduce({}) { |hsh, itx| hsh.merge({ itx["title"] => itx["value_percent"]}) }
 => {"iPhone"=>"42.6", "Windows 7"=>"21.3", "Android"=>"12.8", "Mac OS X"=>"8.5", "Windows 8.1"=>"6.4", "Windows XP"=>"4.3", "Linux"=>"2.1", "Windows Vista"=>"2.1"}