这是一个初学者问题,请帮帮我
my_array = ["city1:state1","city2:state2","city3:state1","city4:state3","city5:state1"]
从这个数组我怎么能像这样做一个哈希?
{
state1: [city1,city3,city5],
state2: [city2],
state3: [city4]
}
我正在尝试这种方式
my_hash = { }
my_array.each do |cs|
temp = cs.split(":")
if my_hash.keys.include? temp[1]
my_hash[temp[1]] = temp[0]
else
my_hash[temp[1]] = temp[0]
end
end
但我没有得到如何匹配我的哈希的键并附加到键。
答案 0 :(得分:3)
可以进行一些修改:
my_hash = { }
my_array.each do |cs|
temp = cs.split(":")
if my_hash.keys.include? temp[1].to_sym
my_hash[temp[1].to_sym] << temp[0]
else
my_hash[temp[1].to_sym] = [temp[0]]
end
end
结果是{:state1=>["city1", "city3", "city5"], :state2=>["city2"], :state3=>["city4"]}
。我假设这是你的意思(键是符号,值是字符串数组)。
答案 1 :(得分:1)
试试这个(考虑到您在问题中输错了state3:[city3]
而不是state3:[city4]
):
my_array = ["city1:state1","city2:state2","city3:state1","city4:state3","city5:state1"]
my_hash = { }
my_array.each do |cs|
value, key = cs.split(":")
key = key.to_sym
if my_hash[key].present?
my_hash[key] << value
else
my_hash[key] = [value]
end
end
my_hash #=> {:state1=>["city1", "city3", "city5"], :state2=>["city2"], :state3=>["city4"]}
或者,单行:
my_hash = my_array.inject({}){|h, cs| value, key = cs.split(":"); key = key.to_sym; h[key].present? ? (h[key] << value) : h[key] = [value]; h }
my_hash #=> {:state1=>["city1", "city3", "city5"], :state2=>["city2"], :state3=>["city4"]}
甚至更好(基于jesper关于Hash的想法):
my_array.inject(Hash.new{|h,k| h[k] = [] }){ |my_hash, cs| value, key = cs.split(":"); my_hash[key.to_sym] << value; my_hash }
my_hash #=> {:state1=>["city1", "city3", "city5"], :state2=>["city2"], :state3=>["city4"]}
答案 2 :(得分:1)
您可以使用哈希默认值来实现替代解决方案:
my_array = ["city1:state1","city2:state2","city3:state1","city4:state3","city5:state1"]
hash = Hash.new do |hash, key|
hash[key] = []
end
my_array.each_with_object(hash) do |string, hash|
city, state = string.split(":")
hash[state.to_sym] << city
end
# => {:state1=>["city1", "city3", "city5"], :state2=>["city2"], :state3=>["city4"]}