使用键入字符串数组的空数组初始化哈希 - Ruby

时间:2016-11-04 06:21:00

标签: ruby hash initialization

我有:

people=["Bob","Fred","Sam"]

holidays = Hash.new 
people.each do |person|
  a=Array.new
  holidays[person]=a
end

gifts = Hash.new
people.each do |person|
  a=Array.new
  gifts[person]=a
end

感觉笨重。我似乎无法用初始化块或某些东西来计算更简洁的方法。这里有一种惯用的方法吗?

理想情况下,我想保留一个像:

这样的数组
lists["holidays","gifts",...]  

...并通过它来初始化列表数组中的每个元素。

3 个答案:

答案 0 :(得分:1)

people = %w|Bob Fred Sam|
data = %w|holidays gifts|

result = data.zip(data.map { people.zip(people.map { [] }).to_h }).to_h
result['holidays']['Bob'] << Date.today
#⇒ {
#    "holidays" => {
#         "Bob" => [
#           [0] #<Date: 2016-11-04 ((2457697j,0s,0n),+0s,2299161j)>
#         ],
#        "Fred" => [],
#         "Sam" => []
#    },
#       "gifts" => {
#         "Bob" => [],
#        "Fred" => [],
#         "Sam" => []
#    }
# }

更复杂的例子是:

result = data.map do |d| 
  [d, Hash.new { |h, k| h[k] = [] if people.include?(k) }]
end.to_h

后者生成“延迟初始化嵌套哈希。”它使用Hash#new with a block构造函数来嵌套哈希。

使用它来查看它是如何工作的。

答案 1 :(得分:0)

这样做的常用方法是使用Enumerable#each_with_objrect

holidays = people.each_with_object({}) { |p,h| h[p] = [] }
  #=> {"Bob"=>[], "Fred"=>[], "Sam"=>[]} 

gifts是一样的。

答案 2 :(得分:-1)

如果你只想要一些这样的哈希值,那么下面就足够了:

count_of_hashes = 4 // lists.count; 4 is chosen randomly by throwing a fair die

people = ["Bob", "Fred", "Sam"]

lists = count_of_hashes.times.map do
  people.map {|person| [person, []]}.to_h
end

此代码还确保数组和散列都占用自己的内存。可以通过以下代码验证:

holidays, gifts, *rest = lists
holidays["Bob"] << "Rome"

检查所有其他哈希的值:

lists
=> [
    {"Bob"=>["Rome"], "Fred"=>[], "Sam"=>[]},
    {"Bob"=>[], "Fred"=>[], "Sam"=>[]},
    {"Bob"=>[], "Fred"=>[], "Sam"=>[]},
    {"Bob"=>[], "Fred"=>[], "Sam"=>[]}
   ]