2014-11-23 81 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)]