如何将多个值推送到相同的哈希键

时间:2014-09-30 08:30:18

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

这是一个初学者问题,请帮帮我

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

但我没有得到如何匹配我的哈希的键并附加到键。

3 个答案:

答案 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"]}