我有:
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",...]
...并通过它来初始化列表数组中的每个元素。
答案 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"=>[]}
]