繁体   English   中英

Ruby hash 带数组值

[英]Ruby hash with array values

假设我有一个像这样的 hash

{"k1"=>["v1"], "k2"=>["v2"], "k3"=>["v3"], "k4"=>["v4"]}

我希望它看起来像这样:

{"k1"=>"v1", "k2"=>"v2", "k3"=>"v3", "k4"=>"v4"}

有没有比这个丑陋的inject更简单的方法呢?

h1 = {"k1"=>["v1"], "k2"=>["v2"], "k3"=>["v3"], "k4"=>["v4"]}
h2 = h1.inject({}){|h,v| h[v.first]=v.last.first; h}

比您的“注入”解决方案更丑:

h1 = {"k1"=>["v1"], "k2"=>["v2"], "k3"=>["v3"], "k4"=>["v4"]}
h2 = Hash[*h1.map.flatten]
h2 # => {"k1"=>"v1", "k2"=>"v2", "k3"=>"v3", "k4"=>"v4"}

正如@the Tin Man 在评论中指出的那样,如果您的值 arrays 可能有多个元素,那么您需要做一些稍微不同的事情才能使其按预期工作:

h2 = Hash[*h1.map{|k,v|[k,v[0]]}.flatten]
h2 # => {"k1"=>"v1", "k2"=>"v2", "k3"=>"v3", "k4"=>"v4"}

您可以使用简单的each就地修改它:

h = {"k1"=>["v1"], "k2"=>["v2"], "k3"=>["v3"], "k4"=>["v4"]}
h.each { |k,v| h[k] = v[0] }

或者,如果你想复制,你可以使用更清洁的inject

flatter_h = h.inject({ }) { |x, (k,v)| x[k] = v[0]; x }

或者,如果您有each_with_object可用(即 Rails 或 Ruby 1.9):

flatter_h = h.each_with_object({ }) { |(k,v), x| x[k] = v[0] }

或许对inject的使用更具吸引力。 Hash#merge是你的朋友:

hash = {"k1"=>["v1"], "k2"=>["v2"], "k3"=>["v3"], "k4"=>["v4"]}
hash.inject({}) {|r,a| r.merge(a.first=>a.last.first)}
>> h = {"k1"=>["v1"], "k2"=>["v2"], "k3"=>["v3"], "k4"=>["v4"]}
>> Hash[h.map { |k, vs| [k, vs.first] }]
=> {"k1"=>"v1", "k2"=>"v2", "k3"=>"v3", "k4"=>"v4"}

结合Hash[h.map { |k, v| [k, v.first] }] Hash[h.map { |k, v| [k, v.first] }]来自@tokland 的答案的语法与@mu 的h.inject({ }) { |x, (k,v)| x[k] = v[0]; x }中引入的数组解构语法h.inject({ }) { |x, (k,v)| x[k] = v[0]; x } h.inject({ }) { |x, (k,v)| x[k] = v[0]; x } ,我想出了我认为最干净的解决方案:

h1 = {"k1"=>["v1"], "k2"=>["v2"], "k3"=>["v3"], "k4"=>["v4"]}
h2 = Hash[h1.map{|k,(v)| [k, v]}]

暂无
暂无

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM