2014-11-23 59 views
1

我仍然很新的编程,我试图将字符串数组转换为符号散列。字符串的格式是给我的悲伤:将红宝石数组转换成带符号的散列

foobar = ["ABC: OPEN", "123: OPEN", "FOO: CLOSED", "BAR: CLOSED", "XYZ: OPEN", "LMO: CLOSED"] 

我试图让这个“名状态”的格式转移到一个散列结果,其中的关键可能是一个符号:

foobar_hash = {"ABC" => :OPEN, "123" => :OPEN, "FOO" => :CLOSED, "BAR" => :CLOSED, "XYZ" => :CLOSED, "LMO" => :CLOSED} 

什么将是完成这个最好的方法?

+0

这实际上是一个体面的代码高尔夫球问题。 – wberry 2014-11-23 18:01:06

+0

是的。对不起,我已经适当地编辑了它 – 2014-11-23 18:15:29

+0

'':OPEN'是否必须是字符串或符号? – Anthony 2014-11-23 18:16:28

回答

0

你可以做这样的事情:如果您在value前需要colon

[4] pry(main)> foobar = ["ABC: OPEN", "123: OPEN", "FOO: CLOSED", "BAR: CLOSED", "XYZ: OPEN", "LMO: CLOSED"] 

=> ["ABC: OPEN", "123: OPEN", "FOO: CLOSED", "BAR: CLOSED", "XYZ: OPEN", "LMO: CLOSED"] 
[5] pry(main)> foobar.map { |i| i.split(": ") }.to_h 
=> {"ABC"=>"OPEN", 
"123"=>"OPEN", 
"FOO"=>"CLOSED", 
"BAR"=>"CLOSED", 
"XYZ"=>"OPEN", 
"LMO"=>"CLOSED"} 

你也可以做这样的事情:

[14] pry(main)> foobar.map { |i| i.gsub(": ", " :") }.map { |j| j.split(" ") }.to_h 
=> {"ABC"=>":OPEN", 
"123"=>":OPEN", 
"FOO"=>":CLOSED", 
"BAR"=>":CLOSED", 
"XYZ"=>":OPEN", 
"LMO"=>":CLOSED"} 

还有一个迭代,如果你需要的值是符号,你可以这样做:

[35] pry(main)> foobar.map { |i| i.split(": ") }.each_with_object({}) do |array, hash| 
[35] pry(main)* hash[array.first] = array.last.to_sym 
[35] pry(main)* end 

=> {"ABC"=>:OPEN, "123"=>:OPEN, "FOO"=>:CLOSED, "BAR"=>:CLOSED, "XYZ"=>:OPEN, "LMO"=>:CLOSED} 
+0

嗯,我得到一个没有方法错误.to_h – 2014-11-23 18:06:29

+1

这很好。需要将.to_h从2.0.0更新到2.1.5。谢谢! – 2014-11-23 18:31:15

4

像这样的东西?

arr = [ 
    "ABC: OPEN", 
    "123: OPEN", 
    "FOO: CLOSED", 
    "BAR: CLOSED", 
    "XYZ: OPEN", 
    "LMO: CLOSED" 
] 

Hash[arr.map { |x| x.split ": " }] 

=> {"ABC"=>"OPEN", 
"123"=>"OPEN", 
"FOO"=>"CLOSED", 
"BAR"=>"CLOSED", 
"XYZ"=>"OPEN", 
"LMO"=>"CLOSED"} 

如果你想符号键/值:Hash[arr.map { |x| x.split(": ").map(&:to_sym) }]

+0

这是整洁! :) – 2014-11-23 18:12:01

+0

OP不能更清楚地表示值是符号,那么为什么你的最后一句话里有更多的东西呢? (+1 +1) – 2014-11-23 19:14:52

+0

@CarySwoveland我是'each_with_object'的_fan_ ... :-) – 2014-11-23 19:15:53

0

这可能会实现:

foobar_hash = {} 
foobar.each { |s| foobar_hash[s.split(":")[0].strip] = s.split(":")[1].strip.to_sym } 
+0

你会删除你的'do'吗? :-) – 2014-11-23 18:16:41

+0

添加'.strip'删除任何尾随的空格。 – 2014-11-23 19:10:31

1

另一种方式: -

arr = [ 
    "ABC: OPEN", 
    "123: OPEN", 
    "FOO: CLOSED", 
    "BAR: CLOSED", 
    "XYZ: OPEN", 
    "LMO: CLOSED" 
] 

arr.each_with_object({}) do |string, hash| 
    key, val = string.scan(/\w+/) 
    hash[key] = val.to_sym 
end 

# => {"ABC"=>:OPEN, 
#  "123"=>:OPEN, 
#  "FOO"=>:CLOSED, 
#  "BAR"=>:CLOSED, 
#  "XYZ"=>:OPEN, 
#  "LMO"=>:CLOSED} 
0
foobar = ["ABC: OPEN", "123: OPEN", "FOO: CLOSED", "BAR: CLOSED", "XYZ: OPEN", "LMO: CLOSED"] 
foo_hash = Hash.new 
foobar.each { |str| k,v = str.split(': '); foo_hash[k] = v.to_sym } 

foo_hash给你

=> {"ABC"=>:OPEN, "123"=>:OPEN, "FOO"=>:CLOSED, "BAR"=>:CLOSED, "XYZ"=>:OPEN, "LMO"=>:CLOSED} 
0

你可以试试这个

keys = "foobar".map{|s|s.split(':')}.map(&:first) 
values = "foobar".map{|s|s.split(':')}.map(&:last) 

Hash[keys.zip(values)]