使用数组中的键创建哈希,并将空数组作为值

时间:2015-06-07 16:43:33

标签: arrays ruby hash

我有数组标签,它包含许多我需要用来创建新Hash(内容)的字符串,其中每个值都是一个空数组。我目前有Hash[*tags.map {|k| [k, nil]}.flatten],但这会返回:

{
  "tag1" => nil,
  "tag2" => nil,
  "tag3" => nil
}

当我想要它

{
  "tag1" => [],
  "tag2" => [],
  "tag3" => []
}
抱歉,这是一个愚蠢的问题,但我已经google了一下,找不到答案。谢谢!

4 个答案:

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