我有数组标签,它包含许多我需要用来创建新Hash(内容)的字符串,其中每个值都是一个空数组。我目前有Hash[*tags.map {|k| [k, nil]}.flatten]
,但这会返回:
{
"tag1" => nil,
"tag2" => nil,
"tag3" => nil
}
当我想要它
时{
"tag1" => [],
"tag2" => [],
"tag3" => []
}
抱歉,这是一个愚蠢的问题,但我已经google了一下,找不到答案。谢谢!
答案 0 :(得分:3)
使用flatten,映射[]
代替nil
,就像您尝试过的那样,然后使用flatten(1)
。这只会消除第一层数组,因此您可以['tag1', [], ...]
传递给Hash[]
。
> tags = %w[tag1 tag2 tag3]
=> ["tag1", "tag2", "tag3"]
> tags.map {|k| [k, []]}.flatten
=> ["tag1", "tag2", "tag3"]
> tags.map {|k| [k, []]}.flatten(1)
=> ["tag1", [], "tag2", [], "tag3", []]
> Hash[*tags.map {|k| [k, []]}.flatten(1)]
=> {"tag1"=>[], "tag2"=>[], "tag3"=>[]}
如果您从flatten
删除splat(*
),也可以完全避免Hash[]
,因为::[]也接受了对的列表。
> tags.map {|k| [k, []]}
=> [["tag1", []], ["tag2", []], ["tag3", []]]
> Hash[tags.map {|k| [k, []]}]
=> {"tag1"=>[], "tag2"=>[], "tag3"=>[]}
答案 1 :(得分:1)
Ruby的Array支持(笛卡尔)产品,因此您可以利用这一点,而无需在块内部构建额外的逻辑:
> tags.product([[]]).to_h
=> {"tag1"=>[], "tag2"=>[], "tag3"=>[]}
简单。
答案 2 :(得分:0)
根据docs Hash.new
接受一个块,您可以使用该块在每次访问不属于Hash的新密钥时提供默认值。
所以你可以使用这个
tags = %w(tag1 tag2 tag3)
h = Hash.new{ |hash, key| hash[key] = [] }
tags.each{ |tag| h[tag] }
# h == {"tag1"=>[], "tag2"=>[], "tag3"=>[]}
h['tag4']
# h == {"tag1"=>[], "tag2"=>[], "tag3"=>[], "tag4"=>[]}
答案 3 :(得分:0)
还有一种方法:
tags = %w|tag1 tag2 tag3|
Hash.new { |h,k| h[k] = [] }.tap { |h| h.values_at(*tags) }
#=> {"tag1"=>[], "tag2"=>[], "tag3"=>[]}